这篇写什么?
卡顿、发热、某模块「是不是把 CPU 打满了」——口头说不准,最好抓一份 atrace,用 Perfetto 看时间线上每个线程占了多少 CPU。
本文按实操顺序写:先记机况 → 再异步开 trace → 复现问题 → 停抓导出 → 导入网页分析。
一句话:
precondition 记机况
→ 重启(尽量别开满屏 logcat)
→ atrace --async_start(带 sched 等类别)
→ 复现问题
→ atrace --async_stop -o trace.bin
→ Perfetto 打开,看 CPU / 线程

一、抓之前:用脚本记一份「机况」
不同频率、不同内存压力下,同一份业务 CPU 占用差很多。所以先跑 precondition,把 SOC、核频、DDR、GPU、Android 版本等记下来,方便对比两次 trace。
1)推脚本并授权
adb push benchmark_precondition.sh /data/local/tmp/
adb shell chmod 777 /data/local/tmp/benchmark_precondition.sh
2)执行(示例)
adb shell /data/local/tmp/benchmark_precondition.sh -s
输出里通常能看到类似信息(数值因机型而异):
| 类别 | 关注点 |
|---|---|
| CPU | SOC 名、在线核、当前频率、governor |
| MEM | DDR 容量/空闲、频率、ZRAM |
| 存储 | eMMC/UFS 规格与时钟 |
| GPU | 型号、频率、利用率 |
| Android | 版本、分辨率、是否 low_ram 等 |

把这段日志和后面的 trace.bin 成对保存,复盘时才知道「当时有没有降频/内存很紧」。
二、重启后再抓:减少干扰
建议:
- 重启 设备,让状态干净
- 不要 同时开超高刷量的
logcat(本身也会占 CPU、刷满缓冲) - 需要 root 时再
su(部分节点要求更高权限)
三、打开平台 atrace 相关开关(按项目)
部分芯片平台会先写 debug 节点,再开 kernel event。下面是一套常见写法(路径/节点名因平台略有差异,以你们树为准):
adb shell
su
# 平台 atrace tag(示例:逐档打开)
echo 0 > /sys/class/debug/atrace_tag
echo 1 > /sys/class/debug/atrace_tag
echo 2 > /sys/class/debug/atrace_tag
echo 3 > /sys/class/debug/atrace_tag
echo 4 > /sys/class/debug/atrace_tag
echo 5 > /sys/class/debug/atrace_tag
echo 6 > /sys/class/debug/atrace_tag
echo 7 > /sys/class/debug/atrace_tag
cat /sys/class/debug/atrace_tag
# 平台/解码相关 event(有则开)
echo 1 > /sys/kernel/debug/tracing/events/meson_atrace/enable
echo 1 > /sys/module/decoder_common/parameters/dec_time_stat_flag
没有这些节点时,可跳过,直接用下一节的 atrace 命令。
四、异步开始抓取
atrace -b 25000 sched gfx irq video binder_driver memreclaim audio binder_lock --async_start
| 参数 | 含义 |
|---|---|
-b 25000 |
环形缓冲大约 25 MB 量级(偏大一点,减少复现时被冲掉) |
sched |
调度 / CPU 占用分析的核心 |
gfx |
图形相关 |
irq |
中断 |
video |
视频通路 |
audio |
音频相关 |
binder_* |
Binder 锁与驱动 |
memreclaim |
内存回收 |
--async_start |
后台开始抓,终端可以去做复现操作 |
类别可按问题裁剪:纯查 CPU 抢核,至少保证有 sched;音画问题再带上 audio / video / gfx。
五、复现问题后停止并导出
问题复现完成后:
atrace -z --async_stop -o /data/local/tmp/trace.bin
| 参数 | 含义 |
|---|---|
--async_stop |
结束异步抓取 |
-z |
压缩(体积更小,上传更快) |
-o .../trace.bin |
输出路径 |
拉到电脑:
adb pull /data/local/tmp/trace.bin .
六、用 Perfetto 看 CPU / 线程
- 打开 https://ui.perfetto.dev
- 点 Open trace file,选择
trace.bin

- 在时间线里重点看:
- CPU 泳道:哪些核在忙
- 进程 / 线程条带:谁在跑、是否可运行排队
- 与问题时刻对齐:卡顿点前后谁突然变密
操作提示:W/A/S/D 缩放平移;用搜索定位进程名(如 audioserver、media.swcodec、自研服务名)。
看 CPU 占用时的实用顺序:
- 缩到「出问题」那几秒
- 看哪条线程颜色最密、持续最长
- 对照 precondition:是否当时已降频、内存吃紧
- 再决定是算法重、锁等待,还是绑核/优先级问题
七、常见坑
| 现象 | 可能原因 |
|---|---|
| trace 很短/几乎空 | 没 async_start 就停了;缓冲太小被冲掉;权限不够 |
| 文件巨大拖不动 | -b 过大 + 抓太久;先 -z,或缩短复现窗口 |
| 看不到调度细节 | 类别里漏了 sched |
| 和上次结论矛盾 | 没记 precondition,频率/governor 不一致 |
| 复现时更卡 | 同时狂打 logcat;先关多余日志再抓 |
八、检查清单
- 已跑 precondition,日志已保存
- 重启后、少开 logcat
-
atrace ... --async_start已执行(含sched) - 完成复现后再
--async_stop -o trace.bin -
adb pull成功,Perfetto 能打开 - 截图/笔记标出「问题时刻」与头号嫌疑线程
总结
查 CPU 占用,不要只靠「顶一下 top」:用 atrace + Perfetto 才能看到时间线上谁在抢核。
流程记成四步——记机况 → 异步开抓 → 复现 → 导出分析——和音频/视频问题复盘时特别好用。
相关阅读
评论
还没有评论,来做第一个吧
赞同、吐槽、提问都行,评论区开放