为什么需要 Systrace 和 Perfetto?

我记得刚做性能优化那会儿,团队里最常用的手段就是看 logcat 和抓 bugreport。说白了,那时候大家觉得卡顿嘛,要么是主线程干了重活,要么是内存泄漏。可随着 App 功能越来越复杂,启动链路上牵扯的模块越来越多,你光靠 logcat 打几个时间戳,根本拼不出一张完整的执行全景图。

为什么会这样?

因为现代移动终端已经不是单核单进程的简单系统了。你点一下屏幕,背后的 I/O、CPU 调度、GPU 渲染、Binder 通信,可能是几十个线程在并行运转。你以为的“主线程卡顿”,根因往往出在别的进程抢占了 CPU 资源,或者 Binder 调用被某个慢服务拖住了。这时候,你就需要一个能从系统全局视角,把时间线精确到微秒级的工具。

这个工具,就是 Systrace,以及它的下一代——Perfetto。

1.1 传统工具到底差在哪?

我遇到过最典型的一个场景:App 某个页面滑动掉帧,Log 里没有任何异常堆栈,Memory 也不高。用 dumpsys gfxinfo 抓了几轮,Draw/Prepare/Process 耗时都正常。你猜怎么着?最后靠 Systrace 一看,发现是 SurfaceFlinger 的 HWC 合成超时,导致 Triple Buffer 没能及时排空。这种问题,你用 Log 或者 Profile 是根本抓不到的。

工具 类别 优势 致命短板
Logcat 日志 简单、随时可打 无法关联时间线、开销不可控
Dumpsys 快照 能看瞬时状态 没有时序演进,看不到过程
Profiler 抽样 方法级热点定位准 开销大,无法覆盖内核态
Systrace/Perfetto 全量 Track 系统全局 + 微秒级时间线 + 低开销 需要理解关键进程模型

你想想看,传统工具要么是“快照”,要么是“抽样”。而性能问题恰恰是一个**时序**问题。帧率为什么掉?因为 A 在等 B,B 在等 C,C 被 D 抢占了 CPU。没有全局时间线,你根本没法还原现场。

核心认知: 性能分析的本质是“时间线分析”。Systrace 和 Perfetto 的核心价值,就是为你提供一张完整、精准的系统级时序图谱。

1.2 从 Systrace 到 Perfetto —— 我经历了什么?

Systrace 其实已经非常强大了。它基于 Linux 内核的 ftrace 机制,通过 atrace 激活用户态的 Trace 点(比如 Binder、SurfaceFlinger、Input),就能抓出全局调度视图。

但是,在实战中我发现 Systrace 有 3 个比较头疼的局限:

  1. 数据格式封闭: 它的 HTML 报告虽然可视化不错,但你想做二次分析、自动化分析,基本没门。
  2. 追踪源有限: 只能抓系统已经定义好的 Trace 点,自定义数据要写内核模块,门槛高。
  3. 长 trace 不稳定: 超过几十秒的 trace 文件会非常大,UI 操作卡顿,甚至打不开。

嗯,这里有个重要的转折点。Google 内部后来启动了 Perfetto 项目,它的目标很明确:统一用户态和内核态的追踪生态,并且把数据模型彻底改造成 protobuf。

Perfetto 的优势是降维打击式的:

  • 数据源更丰富: 除了 ftrace,还能集成 heapprofd(内存分析)、perf(采样)、power rails(功耗)、自带 SQL 分析引擎。
  • 序列化格式先进: protobuf 编码,解析效率高,支持流式写入,轻松抓分钟级甚至小时级的 trace。
  • UI 全面升级: 基于 WebAssembly 的 UI,交互流畅度远超旧版 Systrace 的 HTML 报告。
  • SQL 分析能力: 你可以在 trace 上跑 SQL 查询,比如“找出所有耗时超过 8ms 的 Binder 调用”。这是旧 Systrace 完全做不到的。
特别提醒: 不要以为 Systrace 已经淘汰了。很多老设备或自动化测试环境仍然依赖 systrace 命令。Perfetto 完全向后兼容,但掌握 Systrace 的基本概念,是理解 Perfetto 的基石。

1.3 两种工具的核心使命

无论是 Systrace 还是 Perfetto,它们最终要解决的,其实就是这 4 类问题:

  1. UI Jank(掉帧): 找到 Choreographer 的 doFrame 被什么阻塞了。
  2. 启动速度慢: 分析 cold start 流程中,ContentProvider、Application、Activity 创建各阶段耗时。
  3. CPU 负载异常: 到底哪个线程在持续占用 CPU?优先级是否被翻转?
  4. 功耗异常: 有没有后台频繁 wakeup?WiFi lock 没有释放?

我个人习惯,只要遇到“看起来没报错但用户体验就是差”的情况,第一反应就是拉一份 trace 看看。trace 抓下来,不要急着看细节。先看整体时间线,有没有明显的大段空白或者密密麻麻的 CPU 唤醒点。那些异常区域,就是你分析的切入口。

实战技巧: 我一般在抓 trace 时,会同时让测试同学复现问题并做一个“动作标记”(比如点击屏幕的那一刻在 log 里打印一句特殊标识,或者在代码里加一个 Trace.beginSection("click"))。这样在时间线上能快速对齐用户操作点。

1.4 本章知识体系

性能分析工具演进与核心价值 现实痛点 系统复杂度激增 多核CPU / 多进程架构 vs 传统定位手段匮乏 工具演进路线 传统方案:Logcat / Dumpsys Systrace:基于 ftrace + atrace Perfetto:protobuf + SQL 分析引擎 无法满足 演进 核心使命:解决 UI Jank / 功耗 / 启动问题 全局时间线 + 微秒级精度 + 低开销 最终目标 结论:Perfetto 是未来,但理解 Systrace 的 Trace 点模型是基本功。 (两者共用同一个事件模型,学会一个就能快速上手另一个)

1.5 什么时候该用哪个?

我个人的经验是,可以分成这几种情况:

  • 手头只有 adb 且暂时装不了 Perfetto 环境: 用 systrace.py 或 Android Studio 的 Profiler。快速验证。
  • 需要深入分析长达几分钟的场景(比如后台唤醒、相机预览流): 强烈建议 Perfetto。它的流式抓取能力在这里优势巨大。
  • 要做自动化分析,比如 CI 流水线里检测性能回退: Perfetto 的 SQL 接口是唯一选择。你可以写脚本自动查询 trace 里所有 doFrame 耗时。
  • 分析内存泄漏: Perfetto 的 heapprofd 是内置的,无需再单独用 malloc debug。
一句话总结: Systrace 适合“短时快速排查”,Perfetto 适合“深度系统级定位”。但它们的底层机制完全互通,你只要把 Systrace 的时间线思维学透了,切换到 Perfetto 基本没有学习成本。