Perfetto 故障排查指南:从数据源到分析层的完整排查路径
【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto
你按流程跑了一次追踪,拿到 .pftrace,打开 UI 却发现关键轨道是空的,或者堆转储怎么都解析不了。这类 Perfetto 故障排查其实有固定套路:一条 trace 要经过数据源(采什么)、采集(权限、buffer、触发器)、分析(trace_processor 和 UI)三层,绝大多数"失败"都能归到其中一层。先判断故障在哪一层,再逐层深挖,比盲目换参数快得多。
先判断故障属于哪一层:数据源、采集还是分析
别急着改配置,先做一次最小验证:文件能不能被打开,打开后目标表里有没有行。
下面这条命令用 trace_processor 直接数行数,确认数据源对应的表是否真的有数据:
tools/trace_processor trace.pftrace -q "SELECT name, count(*) FROM thread GROUP BY name"文件打不开,问题在文件本身或分析工具版本;能打开但表是空的,按数据源层、采集层的顺序排查。
| 症状 | 大概率所在层 |
|---|---|
| trace_processor 报错、打不开文件 | 文件 / 分析层 |
| 能打开,但目标表 0 行 | 数据源层 / 采集层 |
| 有数据但堆栈全是地址 | 符号解析(分析层) |
| 堆转储没抓到 / 抓不到 OOM 时刻 | 采集层(触发器、权限) |
数据源层:配置没生效与版本门槛
确认数据源在配置里且系统版本支持
不同数据源有硬性版本要求:heapprofd 需要 Android 10+,java_hprof 需要 Android 11+,OOM 自动转储需要 Android 14+。设备版本不满足时,配置写得再对也是 0 行,这是内存分析失败最常见的一个原因。确认版本后,再看数据源名字和 config 字段是否拼写正确、有没有写进实际的 trace_config 里。
把 JSON 事件换成 TrackEvent
如果你还在用 B/E 这类 JSON 事件,建议把采集端切到 TrackEvent。这段配置启用 track_event 数据源并收集所有类别:
data_sources: { config { name: "track_event" track_event_config { enabled_categories: "*" } } }改采集端的事件发出方式为 TrackEvent,后面分析层的一大类解析问题就不存在了;转换方法可参考 docs/reference/synthetic-track-event.md。
检查过滤条件有没有把目标挡在外面
ftrace_events、atrace_apps、process_cmdline 这类字段写错一个字符,整条数据源就静默失效。特别提醒 process_cmdline:Android 13 起匹配规则变了,12 及以下按规范化后的字符串精确比较。用adb shell ps核对一遍实际命令行,能排除掉大部分"配了却没数据"的问题。
采集层:权限、buffer 与触发器
确认目标应用可被 profile 的两种方式
采集堆数据的前提是系统允许 attach 目标进程。两种方式满足其一即可:应用是 debuggable 的,或者在 manifest 里显式标记 profileable:
<application android:profileable="true" />release 包默认关 debuggable,需要补上这行并重装应用,否则 heapprofd、java_hprof 一律采不到。
Perfetto OOM 堆转储自动捕获
Android 14 上可以让 Java 进程 OOM 时自动抓转储。这段配置启用 android.java_hprof.oom 数据源,trigger_config 采用 START_TRACING 模式:收到系统 OOM 信号才开始采,一小时超时,停止时留 500ms 余量:
cat << 'EOF' | adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/oome.pftrace buffers: { size_kb: 512288 fill_policy: DISCARD } data_sources: { config { name: "android.java_hprof.oom" java_hprof_config { process_cmdline: "*" } } } trigger_config { trigger_mode: START_TRACING trigger_timeout_ms: 3600000 triggers { name: "com.android.telemetry.art-outofmemory" stop_delay_ms: 500 } } EOF转储没抓到时先查 trigger_timeout_ms 是不是在 OOM 发生前就超时了,再核对 trigger 的 name 与设备实际发出的系统事件是否一致;完整用法见 docs/getting-started/local-android-trace-recording.md。
Java 堆转储失败与解析问题
手动抓转储用tools/java_heap_dump -n com.android.systemui这类命令,dump 失败多与设备剩余存储空间不足、进程内存状态不稳有关。解析侧可以用 UI 的 Focus 功能按对象类型过滤,先缩小范围再查,别对着全量图找。界面长这样:
Perfetto 原生堆符号解析失败的三种原因
⚠️ 火焰图上一片裸地址时,按这个顺序查:设备上缺少符号信息、host 端 heap_profile 工具版本过旧、设备与工具架构不匹配(32/64 位)。工具更新到与设备 perfetto 版本一致,并确认目标 so 带符号表,是绝大多数场景的解法,详见 docs/data-sources/native-heap-profiler.md。
实战:相机 App 拍照后内存持续增长,最终被 LMK 杀掉
现象是相机进程每次拍照后 RSS 只涨不降,最后触发 LMK。排查按层走一遍:
采集层:先让 trace 能看到"杀"这个动作本身。这段配置监听 lowmemory_kill 事件,并用 atrace 跟踪 lmkd 进程;oom_score_adj 的变化则交给 process_stats 数据源按周期采样:
data_sources: { config { name: "linux.ftrace" ftrace_config { ftrace_events: "lowmemorykiller/lowmemory_kill" atrace_apps: "lmkd" } } }trace 里有 RSS 曲线但没有 kill 事件时,多半是 ftrace_events 没列上 lowmemorykiller,或内核不支持该事件。
数据源层:在拍照操作前后分别打内存快照(process_stats 计数器 + 原生堆 / Java 堆转储),确保泄漏区间被完整覆盖。
分析层:对比两份快照的分配差异,用 Focus 过滤 "notification" 相关对象,最终定位到通知子系统的对象只入不出,泄漏点随之浮出。完整的相机案例 walkthrough 在 docs/case-studies/memory.md。
分析层:数据对不上与格式坑
JSON 格式追踪的兼容坑
JSON 是遗留格式,Perfetto 只做尽力而为的解析:重叠的 B/E/X 事件显示不正确、部分特性直接不支持。症状是"数据明明采了,UI 里却对不上或缺失"。解法和前面一致:采集端换 TrackEvent;短期无法改动时,确认用与录制端匹配版本的分析工具打开。
用最小 SQL 验证分析结果
分析层排错的关键动作是写最小 SQL 对账,比如SELECT name, count(*) FROM slice看总量是否符合预期。另一类高频问题是录制端与分析端版本不匹配:trace 里新增的表和字段在旧版 trace_processor 里根本不存在,升级分析工具通常直接解决,参见 docs/analysis/trace-processor.md。
故障速查清单
| 症状 | 所在层 | 首先检查 |
|---|---|---|
| JSON trace 事件重叠、字段缺失 | 分析层 | 采集端改 TrackEvent |
| trace_processor 打不开文件 | 文件 / 分析层 | 文件完整性、工具版本 |
| 目标表 0 行 | 数据源层 | 数据源名、系统版本、过滤条件 |
| heapprofd / java_hprof 采不到 | 采集层 | debuggable 或 profileable |
| OOM 转储没抓到 | 采集层 | trigger 超时时间、trigger name |
| 原生堆全是裸地址 | 符号解析 | 工具版本、架构、符号表 |
| 堆转储解析慢 / 失败 | 分析层 | 存储空间、Focus 过滤 |
| RSS 只涨不降、进程被杀 | 系统侧 | ftrace lowmemory_kill + lmkd |
【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考