目录

一次 CPU 问题的排查

前言

最近来了个新环境,做了第一个需求——直播答题

这边的风格大致就是:先在能使用的库的基础上快速完成需求,整个开发时间大概在2-3周,客户端总共俩人,我主要负责直播间内的业务逻辑。

直播间还是很简易的,没有礼物啊什么的,只有个弹幕聊天。

但是因为后端并没有长链接,所以弹幕、直播人数需要轮训来获取,感觉不太妙。

总之,最后算是很挫的完成了任务吧!

收获是,了解了一些音视频和直播答题的方案(好的方案需要音视频配合,但是需要他们排期,最后用了一个比较挫,但是能用的方案),还有就是终于用上了 databinding,但是感觉用的很烂,kotlin 依然还是没在真实开发使用,主要这次有点赶,没敢用,下次一定。

但是,最终性能测试没有通过。因为有的设备性能很差,加上系统本身有一些基础服务占用 cpu,性能测试要求 app process cpu < 60%, total cpu < 80%

直播答题的 app 因为有音视频编解码,在最低端的设备上最终 app process cpu 40%, total cpu 80.25%(超标)

那咋办呢?

CPU 过高怎么查

作为一个合格的工程师,当然是打开了 Google -> Android CPU 过高怎么办

基本就是说用 profiler 或者 adb 命令看一下,但是并没有具体的分析。

我感觉应该分为下面几个步骤:

  1. 确定复现场景(哪个页面 cpu 高? 哪个场景 cpu 高?)
    如果这个找不到,那根本无从查起了,比如我这边就是进入直播间 cpu 占用变高。

  2. 场景中有哪些消耗 cpu 的场景?控制变量,进一步缩小范围
    比如我的直播间 cpu 过高的话,直播间有 轮训的网络请求、动画、播放器,这三个可能会比较耗费 cpu 的东西,分别注释掉其余两个,看看到底是谁的锅?
    需要有足够的耐心!

  3. 确定到具体的小方面,profiler 查看具体问题
    我最终通过注释代码,发现大部分 cpu 是播放器的锅,但是播放器使用的是别的部门的,而且应该也是线上用的,想要给他们反馈 bug,肯定要有十足的证据。

通过前面的方法论,我当时基本确定了问题出现的场景:重新进出直播间,cpu 就会上涨 15% 左右(只上涨一次,只在一批固定低端设备产生问题)

所以,问题也很诡异,一开始反馈给播放器部门,他们尝试复现,结果并没有复现出来。

可是,这个问题不修复,总觉得好像是我不太行,第一个需求就因为 cpu 被卡了,所以只能用 profiler 来慢慢看了。

Profiler 分析 CPU

profiler 的使用就不多说了,android studio 直接使用,attach 到对应进程上就好了。

当时的 cpu 如下图:

/img/in-post/cpu_problem.png

Home 页面有一个可以预览的小的 VideoView

home(cpu 20%) -> 其他页面(静态页面 cpu 基本0) -> 返回home(cpu 36%)

具体的分析过程,用了半天左右,怀疑过各种问题

  1. log 里看到有播放器 error,以为是播放器出错导致(后面发现,似乎这个 error 一直有···,排除)
  2. 播放器部门同学说是不是存在泄漏,所以看了下内存,播放器实例,也是一个引用
  3. 有的小伙伴说是不是因为设备太差 GC 呢?然后图里有个 heaptaskdaemon 确实一直在运行,当时看了老久这方面

最终只好对比前后的线程数变化,最终发现了一个可疑的线程,然后通过 method tracing 发现了问题,如下图:

/img/in-post/cpu_problem_2.png

/img/in-post/cpu_problem_3.png

当 CPU 上涨的时候,伴随着这个诡异的 APM_TaskQueue 线程的疯狂运行,甚至比主线程还忙,看起来是个循环才会这样。看名字像是个队列,盲猜是一个神奇逻辑导致队列任务过多,执行任务使用的 while(true) 么?然后也永远执行不完?

然后 record 一段时间,打开具体的 tracing 看了一下,包名也是来自播放器提供的一个 jar 包内,似乎是做埋点上报的。

将以上截图发送播放器部门,他们重新出了一个包,说是依赖了这个第三方埋点库,这个库的问题导致的,最终 total cpu = 64%,通过性能测试,问题解决(但是看他们解决的速度,我咋感觉是直接把这个库干掉了?)

总结

cpu 问题现在应该基本遇不到了,只有低端设备才会出现这些问题,都是具体问题具体分析的。

基本就是围绕着 cpu、内存和帧率来看的,这几个有时候会互相影响。

我遇到的这个问题很简单,通过 profiler 就能分析的出,android 的其他的诡异问题可是太多了!令人头秃!

这个项目写完,感觉自己对于 databinding 和 viewmodel 的使用很烂。

看另一个哥们写的就很简洁、灵动。

加油呗!

生日快乐