3. 性能分析工具链入门

Android Framework 性能与稳定性优化,第一步不是“改代码”,而是“看清现场”。同一个卡顿问题,可能是 CPU 调度、锁竞争、Binder 阻塞、GC 抖动、IO 等待或渲染掉帧,不同根因需要不同工具来定位。本节把常用工具链按“观测层次”串起来:系统级全局观测、进程/线程级采样、方法级追踪、系统服务状态快照,形成一套可复用的排查路径。

一、核心原理:工具链的分层观测模型

性能工具的本质差异在于“观测粒度”和“采样方式”。top/ps 提供进程级瞬时快照,适合快速判断谁在吃 CPU、内存是否异常;dumpsys 输出系统服务内部状态,适合查看 Activity、Window、Package、Battery 等服务的运行态;Systrace/Perfetto 基于 atrace 标签,采集内核与用户态事件,能还原一帧内的调度、渲染、Binder 时序;Traceview 是方法级插桩追踪,能看到每个方法的调用耗时与调用栈;Simpleperf 基于硬件/软件 PMU 采样,适合定位热点函数与 CPU 周期消耗。

排查顺序建议:先用 top/ps 判断“哪个进程异常”,再用 dumpsys 看“服务状态是否正常”,接着用 Perfetto/Systrace 看“时间线上谁阻塞了谁”,最后用 Simpleperf/Traceview 下钻到“具体函数/方法”。
Android 性能分析工具链:分层观测与下钻路径 系统级全局观测 top / ps / dumpsys 时间线追踪 Perfetto / Systrace 方法级追踪 Traceview / Method Tracing CPU 采样剖析 Simpleperf 进程 / 线程 CPU、内存、状态 谁在跑?占用多少?是否 ANR? 调度、渲染、Binder、锁、IO 时序 谁阻塞了谁?一帧为何超时? 方法调用耗时与调用栈 热点方法在哪?调用链多深? 函数级 CPU 周期与热点 native 热点、指令级消耗 快速定位异常进程 ANR、内存暴涨、CPU 飙高 卡顿掉帧、启动慢 帧率、Binder、锁竞争分析 主线程耗时方法定位 onCreate、measure/layout native 库与算法热点 编解码、图像处理、加密 下钻路径:全局异常 → 时间线阻塞 → 方法热点 → 函数级根因

二、方法流程:从“现象”到“根因”的四步法

  1. 第一步:进程级快照。使用 top -H -p <pid> 查看线程级 CPU 占用,ps -A -o PID,PPID,NAME,RSS,STAT 查看进程状态与内存。若发现某线程长期处于 R 状态且 CPU 高,说明是计算密集;若处于 D 状态,则可能是 IO 等待。
  2. 第二步:系统服务状态。用 dumpsys activity activities 查看 Activity 栈与生命周期,dumpsys window 查看窗口焦点与动画,dumpsys batterystats 查看功耗异常。ANR 场景下 dumpsys activity anr 能直接给出 ANR 原因与堆栈。
  3. 第三步:时间线追踪。使用 Perfetto 抓取 atrace 标签,重点关注 sched、freq、binder、gfx、view 等类别。Systrace 适合快速查看帧渲染与主线程阻塞,Perfetto 则支持更长时间、更大数据量的 SQL 查询分析。
  4. 第四步:函数级下钻。对 native 热点使用 Simpleperf 采样,对 Java 方法使用 Traceview 或 Android Studio Profiler。Simpleperf 的 --call-graph dwarf 能还原调用栈,Traceview 的 Incl/Excl 时间能区分自身耗时与子调用耗时。

三、常用命令与参数速查

# 1. 进程与线程级观测
top -H -p 12345                 # 查看指定进程的线程 CPU 占用
ps -A -o PID,PPID,NAME,RSS,STAT # 查看所有进程状态与内存
dumpsys meminfo com.example.app # 查看应用内存分布

# 2. 系统服务状态
dumpsys activity activities     # Activity 栈与生命周期
dumpsys window windows          # 窗口焦点与层级
dumpsys activity anr            # ANR 原因与堆栈

# 3. Perfetto 抓取(命令行)
perfetto -c - --txt -o /data/misc/perfetto-traces/trace.pftrace <<EOF
buffers: { size_kb: 65536 }
data_sources: {
  config {
    name: "linux.ftrace"
    ftrace_config {
      ftrace_events: "sched/sched_switch"
      ftrace_events: "binder/binder_transaction"
      atrace_categories: "gfx"
      atrace_categories: "view"
    }
  }
}
duration_ms: 10000
EOF

# 4. Simpleperf 采样
simpleperf record -p 12345 -g --duration 10 -o /data/local/tmp/perf.data
simpleperf report -i /data/local/tmp/perf.data --sort dso,symbol

四、工具适用场景对比

工具 观测粒度 典型场景 优点 局限
top / ps 进程 / 线程 CPU 飙高、内存异常、ANR 初筛 轻量、实时、无需配置 无时间线,无法定位调用链
dumpsys 系统服务状态 Activity 栈、窗口、ANR、电量 信息全、可直接看到服务内部状态 输出冗长,需熟悉服务字段
Systrace 系统时间线 掉帧、启动慢、Binder 阻塞 可视化强,适合快速定位帧问题 数据量有限,长时间抓取易丢事件
Perfetto 系统时间线 + SQL 复杂卡顿、跨进程时序、长时追踪 支持 SQL 查询、数据量大、可扩展 学习成本高于 Systrace
Traceview Java 方法级 主线程耗时方法、调用链分析 方法级耗时清晰,Incl/Excl 直观 插桩开销大,不适合线上
Simpleperf 函数 / 指令级 native 热点、算法优化、CPU 周期 采样开销低,支持调用栈 需要符号表,Java 层支持有限

五、案例与误区复盘

案例:某应用滑动列表时偶发掉帧。先用 top -H 发现主线程 CPU 并不高,排除计算密集;再用 Perfetto 抓取 5 秒 trace,发现主线程频繁等待 binder_transaction 返回,进一步查看是某个系统服务调用耗时过长;最后用 dumpsys activity services 确认该服务内部有锁竞争。整个定位过程从“现象”到“根因”只用了三层工具。

常见误区:① 一上来就用 Traceview,插桩开销本身会放大卡顿,导致数据失真;② 只看 CPU 占用,忽略 D 状态 IO 等待和 Binder 阻塞;③ Systrace 抓取时间过长,事件被覆盖,关键帧丢失;④ Simpleperf 未带符号表,报告全是地址无法阅读;⑤ 把 dumpsys 输出当成“日志”而不是“状态快照”,忽略字段含义。
实践建议:建立“工具组合拳”意识——top/ps 做初筛,dumpsys 看状态,Perfetto/Systrace 看时序,Simpleperf/Traceview 做下钻。每次排查后记录工具、命令、关键字段与结论,形成团队可复用的性能排查手册。

掌握这套工具链的关键,不在于记住所有参数,而在于理解每种工具“能看到什么、看不到什么”。只有把观测层次与问题类型匹配起来,才能在复杂的 Framework 性能问题中快速收敛到根因。