基础知识
造成卡顿的原因很多,不过最终都会反映到 CPU 的时间上。
CPU 时间分为两种:
- 用户时间:执行用户态应用程序代码所消耗的时间;
- 系统时间:执行内核态系统调用所消耗的时间,包括 I/O、锁、中断以及其它系统调用的时间。
1. CPU 性能
- 获取 CPU 核心数
cat /sys/devices/system/cpu/possible
0-7
- 获取某个 CPU 的频率
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
2016000
2. 卡顿问题分析指标
2.1 出现问题后,首先应该查看 CPU 的使用率
/proc/stat # 整个系统的 CPU 使用情况
/proc/[pid]/stat # 某个进程的 CPU 使用情况
Linux环境下进程的CPU占用率
其中比较重要的字段有:
proc/self/stat:
utime: 用户时间,反应用户代码执行的耗时
stime: 系统时间,反应系统调用执行的耗时
majorFaults:需要硬盘拷贝的缺页次数
minorFaults:无需硬盘拷贝的缺页次数
如果 CPU 使用率长期大于 60% ,表示系统处于繁忙状态,就需要进一步分析用户时间和系统时间的比例。
对于普通应用程序,系统时间不会长期高于 30%,如果超过这个值,应该进一步检查是 I/O 过多,还是其他系统调用问题。
几个常用的命令:
- top 命名查看哪个进程是 CPU 的消耗大户;
- vmstat 命令实时动态监控操作系统的虚拟内存和 CPU 活动;
- strace 跟踪某个进程中所有的系统调用
2.2 还需要查看 CPU 的饱和度
CPU 饱和度反映的是线程排队等待 CPU 的情况,也就是 CPU 的负载情况。
CPU 饱和度首先会跟应用的线程数有关,如果启动线程过多,容易导致系统不断地切换执行的线程,把大量的时间浪费在上下文切换。
3. Android 卡顿排查工具
3.1 Traceview
3.2 systrace
通常可以使用 systrace 跟踪系统的 I/O 操作、CPU 负载、Surface 渲染、GC 等事件。
3.3 Simpleperf
分析 Native 代码的耗时
4. 可视化方法
4.1 Call Chart
Call Chart 是 Traceview 和 systrace 默认使用的展示方式。它按照应用程序的函数执行顺序来展示,适合用于分析整个流程调用。
A 函数调用 B 函数,B 函数调用 C 函数,循环三次,如下
4.2 Flame Chart
火焰图,以一个全局的视野来看待一段时间的调用分布,可以很自然地把时间和空间两个维度上的信息融合在一张图上。