课程介绍与学习目标:dumpsys 与 Systrace 联合排查的价值
大家好,我是你们的老朋友。做 Android 性能优化这么多年,我踩过的坑不比写的代码少。今天这门课要聊的,是两个最常用的调试工具——dumpsys 和 Systrace。
很多人觉得它们各自孤立的用法都懂,但真正遇到线上卡顿、内存泄漏、ANR 时,还是抓瞎。我当初也这样。直到有一次线上用户反馈某页面滑动掉帧,我单用 dumpsys 查了内存,单用 Systrace 看了渲染,折腾两天没结果。后来强行把两边的日志对到一起,才发现是某个 Service 的 Binder 调用塞住了主线程。嗯,从那以后,我就养成了联合排查的习惯。
这节课我们先理清基础概念,再搭一个整体框架。你想想看,如果连工具各自能干什么都不清楚,怎么谈联合?
1. dumpsys:系统的「体检报告」
dumpsys 是 Android 系统自带的一个命令行工具,可以拉取几乎所有系统服务的内部状态。说白了,它就像医院的体检报告——想查哪个「器官」,就 dump 哪个。
常用场景我列一下:
- 内存分析:
adb shell dumpsys meminfo <包名>,看 Java Heap、Native Heap、Graphics 等占用。 - 电量统计:
adb shell dumpsys batterystats,定位高耗电模块。 - 活动栈:
adb shell dumpsys activity,查看当前栈顶 Activity、进程状态。 - 窗口信息:
adb shell dumpsys window,检查窗口层级、Focus 信息。 - 网络统计:
adb shell dumpsys netstats,看流量分布。
我在项目里遇到过一个 ANR,主线程被一个 ContentProvider 的 query 卡了十几秒。当时就是靠 dumpsys activity processes 看到了线程堆栈的 Binder 调用,才定位到问题。不过它也有短板——它是静态快照,看不到时间线上谁先谁后。
2. Systrace:性能分析的「录像机」
Systrace(现在一般用 Perfetto 替代,但核心概念一样)能把系统关键事件按时间戳记录下来,形成一条五颜六色的时间线。你可以清晰看到:CPU 各核调度、合成 VSYNC 的间隔、主线程是否在干活、Binder 调用耗时、SurfaceFlinger 合成节奏等等。
举个例子:
看掉帧:打开 Systrace,找到 sf 进程的 VSYNC 标记,如果 doFrame 前后出现了 Choreographer#doFrame 被延迟,或者 performTraversals 耗时超过 16ms,那就叫「一次掉帧」。
我负责的一个视频 App,用户反馈划动列表卡顿,用 Systrace 一看,滑动时主线程每隔 500ms 就去写 SharedPreferences 做上报聚合——明显是故意的,改成了批量延时写入,帧率瞬间回到 55fps。但 Systrace 的问题是:它只能告诉你「什么时候卡了」,但不太容易告诉你「是哪个具体的数据结构炸了」。
3. 为什么需要联合排查?
你想想看:dumpsys 给的是「状态」,Systrace 给的是「过程」。两者结合起来,才是一个完整的故事。
我用一个表格总结它们的关系:
| 工具 | 输出内容 | 优势 | 劣势 |
|---|---|---|---|
| dumpsys | 当前各服务内部状态、数值、堆栈 | 深度直击数据结构、内存分布 | 静态快照,没有时间线 |
| Systrace | 时间线事件、线程调度、函数耗时 | 全局时间视角,定位卡顿时刻 | 难以获取内部数据细节 |
| 联合使用 | 先看时间线锁定「什么时候出问题」 再用 dumpsys 查「那个时刻的系统状态」 | 交叉印证,还原真相 | 需要手动对齐时间戳 |
记得有一次排查内存泄漏,Systrace 显示某个 Activity 退出后堆内存一直没下降,但不知道哪里持有引用。于是我在退出瞬间前后分别 dump 了 adb shell dumpsys meminfo 和 dumpsys activity processes,对比出来一个 Observer 持有 Activity 的强引用。如果没有时间线上的证据,我根本不知道该在哪一秒去 dump。
4. 本章的知识结构图
下面这张图把整个课程的知识体系先摆出来。你可以看清 dumpsys、Systrace、以及它们如何交汇成联合排查的完整工作流。
5. 课程整体框架一览
这门课一共 30 章,我会从基础命令讲起,手把手带你做实战案例。这里给出接下来的几个核心模块:
- 基础篇:dumpsys 常用服务详解、Systrace 抓取与解读技巧。
- 联合排查方法论:如何对齐时间戳、如何建立排查 checklist。
- 实战篇:内存泄漏、ANR、掉帧、启动优化等真实 case。
- 进阶篇:与 Perfetto、SimplePerf 等工具搭配,构建自己的性能调优工具链。
个人小建议:别一口气把所有命令背下来。先跟我一起练两个实战 case,你会自然记住那些高频参数。我曾经要求团队新同学两天背完所有 dumpsys 参数,结果没人能做到——后来改成边查边用,两周后大家都能熟练调用了。
6. 做好联合排查的前提
两条硬性要求:
- 能抓取到有意义的时间戳:dumpsys 结果里通常有 SystemClock.elapsedRealtime 或 uptimeMillis,Systrace 也有时间轴。需要你在抓取时记录手机当前时间(比如用
date命令)来做标尺。 - 理解关键线程和进程:至少要知道主线程(UI Thread)、Binder Thread、RenderThread、SurfaceFlinger 这些角色。
我曾经踩过的坑:有次一边 dump 一边抓 trace,结果忘记记下 dump 的精确时间,后面怎么也找不到对应分段。后来我强制自己在每步操作前敲一次 echo "---- $(date) ----" 到日志里,再也没丢过对齐点。
好了,这一章先到这。工具熟悉了,框架搭好了,接下来我们就要进入实战,先把 dumpsys 的几个核心服务翻个底朝天。