profiler 与 trace:方法级与帧级性能分析
2026/8/9大约 3 分钟调试工具Android 14profilertrace性能分析
profiler 与 trace:方法级与帧级性能分析
上一章看了命令族。这一章回答:方法级(哪个方法慢)与帧级(哪帧超时)的性能证据 怎么抓、怎么读?
Method Trace 记录方法进入退出,定位细但插桩开销较大;CPU sampling 以统计方式观察热点; 帧数据判断是否错过呈现期限。工具结论都要回到低干扰的真实场景复核。
插桩、采样与帧数据不能互相替代
| 常见误解 | 正确理解 |
|---|---|
| Method Trace 没有开销 | 它逐方法记录,有可感知开销,结论要在真实场景复核 |
| CPU 采样等于方法耗时 | 采样按时间点抓栈,耗时分布是统计估计 |
| 帧轨迹只有开发者选项能看 | dumpsys gfxinfo 与命令行都能拿帧数据 |
核心结论
- Method Trace 适合定位“方法内部耗时长”,有运行时开销。
- CPU 采样适合定位“哪个线程吃 CPU”,结果是统计分布。
- 帧轨迹(gfxinfo framestats)定位掉帧环节,配合 Perfetto 验证。
- 抓取原则:真实设备、真实场景、短时抓取、多次对比。
- 结论需要结合系统时间线(Perfetto)与业务日志复核。
工具选择与抓取主链
逐步解释:
- 选工具:方法耗时、CPU 分布、帧掉帧分别选对应工具。
- 真实抓取:在真实设备与场景中短时抓取。
- 复核:用 Perfetto 与日志确认结果不是工具开销或偶发。
常用命令
环境:开发设备或模拟器;以下命令不需要 root。
adb shell am profile start <包名> /data/local/tmp/trace.trace
adb shell am profile stop <包名>
adb shell dumpsys gfxinfo <包名> framestats
adb shell dumpsys gfxinfo <包名> | grep -E "Janky|50th|95th"Method Trace 用 am profile 抓取后导入 Android Studio;帧数据用 gfxinfo 汇总与 framestats 明细。抓取期间保持场景单一,避免污染样本。
源码证据
阅读目标:确认 Method Trace 与帧统计入口。
正文指针:Debug.java startMethodTracing();Choreographer.java doFrame(); dumpsys gfxinfo 的帧统计实现。
// Debug.java(伪代码,行号以 r75 为准)
public static void startMethodTracing(String tracePath) { ... }这段代码证明: Method Trace 由 ART 记录方法调用;帧统计由 Choreographer 与 图形系统提供。两者都是“观测”,结论要与真实体验对照。
验证与排障
环境:开发设备或模拟器;trace 文件在本机用 Android Studio 打开。
adb pull /data/local/tmp/trace.trace
adb shell dumpsys gfxinfo <包名> | grep -iE "total|janky"先看方法级热点,再看帧统计;如果方法热点与掉帧时间对不上,用 Perfetto 看系统级 调度与合成。工具结果互相印证才算定位。
常见误区
- “Method Trace 无开销”:有开销,结论要复核。
- “采样等于精确耗时”:采样是统计估计。
- “只在模拟器验证”:调度与 GPU 差异大,必须真机。
- “一次抓取就够”:多次对比才能排除偶发。
延伸问题
- Method Trace 与采样模式的开销差异有多大?
- framestats 各字段分别代表哪个阶段?
- 如何把方法热点与 Perfetto 线程状态对齐?
- 线上如何低成本采集方法级数据?
源码入口
| 文件 | 关键位置 | 作用 |
|---|---|---|
Debug.java | startMethodTracing() | 方法级记录 |
Choreographer.java | doFrame() | 帧回调 |
dumpsys gfxinfo | framestats | 帧明细 |
| ART profiler | 采样实现 | CPU 采样 |
公共路径:frameworks/base/core/java/android/os/ 与 art/runtime/。行号以 r75 检索为准。
难以稳定复现时如何保存现场,见 断点调试与证据文件。