原理
CPU的问题一般分为以下三类:
1、CPU资源冗余使用:
关于这个问题的原因,可能是算法太烂,明明可以只遍历一次却遍历了两次,主要出现在查找、排序、删除等环节;也可能是没有用缓存,明明解码过一次的图片还重复解码;还有就是明明使用int就足够,偏偏要用long,导致CPU的运算压力多出4倍。
2、CPU资源争抢:
- 抢主线程的CPU资源;这是最常见的问题,关键是主线程起码在Android 6.0版之前,没有renderthread的时候,其繁忙程度就决定了是否会引发用户的卡顿问题。
- 抢音视频的CPU资源;跟主线程的情况不同,音视频编解码本身就消耗了大量的CPU资源,同时音视频编解码对于解码的速度是有硬要求的,达不到就会有产生播放流畅度的问题。
- 大家平等,相互抢,比如你开了20个线程做图片解码,那就是相互抢,最终效果就是导致图片的显示速度非常慢。
3、CPU资源利用率低:
CPU就是速度与负载的博弈,用得多会耗电、会卡顿,用得少也会有问题,像启动、界面切换、音视频编解码这些场景,为了保证其速度,不好好利用CPU,真对不起核心数的不断飙升。而导致无法充分利用CPU的因素,除了磁盘和网络I/O外,还有锁操作、sleep等。其中锁的优化,一般在锁的范围上,主要是尽可能地缩减范围。
方案
下面重点讲一下做CPU性能测试过程中的采集方法:
1、top命令
adb shell top | grep 包名
top命令大家应该是非常熟悉的了,依靠adb shell top就可以简单地列出进程的各种信息,缺点就是top本身的性能消耗就不少,所以我们在自动化测试里面的取值,一般不用top。
2、proc下的CPU信息
cat /proc/[pid]/stat
Google 在Android Monitor工具中收集CPU的方法也是采用这种方式,这种方式的原理跟top相似,但性能损耗要小很多,建议自动化测试采用这种方式,下面是命令返回字段的说明:
获取应用pid:
adb shell ps | grep 包名 | awk '{print $2}' | sed -n 1p
计算应用进程的总CPU时间:
utime + stime + cutime + cstim adb shell cat /proc/[pid]/stat | awk '{print $14+$15+$16+$17}'
计算CPU总时间:
对应的指标分别是:user + nice+ system+ idle+ iowait+ irq+ softirq
一段时间内应用进程CPU使用率:(进程CPU总时间2-进程CPU总时间1) / (CPU总时间2-CPU总时间1) * 100%
3、dumpsys cpuinfo
adb shell dumpsys cpuinfo | grep 包名
这种方式虽然比top更简洁,但是准确性没有top高。