课程介绍与学习目标: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、以及它们如何交汇成联合排查的完整工作流。

dumpsys & Systrace 联合排查知识框架 dumpsys 联合排查 Systrace 内存分析 Binder状态 堆栈抓取 电量统计 帧率轨迹 线程调度 Binder延迟 SurfaceFlinger合成 定位卡顿根因 发现内存泄漏 解决ANR/丢帧 核心思路:Systrace 锁定时间点 → dumpsys 挖出状态值 → 交叉对比找到根因

5. 课程整体框架一览

这门课一共 30 章,我会从基础命令讲起,手把手带你做实战案例。这里给出接下来的几个核心模块:

  1. 基础篇:dumpsys 常用服务详解、Systrace 抓取与解读技巧。
  2. 联合排查方法论:如何对齐时间戳、如何建立排查 checklist。
  3. 实战篇:内存泄漏、ANR、掉帧、启动优化等真实 case。
  4. 进阶篇:与 Perfetto、SimplePerf 等工具搭配,构建自己的性能调优工具链。

个人小建议:别一口气把所有命令背下来。先跟我一起练两个实战 case,你会自然记住那些高频参数。我曾经要求团队新同学两天背完所有 dumpsys 参数,结果没人能做到——后来改成边查边用,两周后大家都能熟练调用了。

6. 做好联合排查的前提

两条硬性要求:

  • 能抓取到有意义的时间戳:dumpsys 结果里通常有 SystemClock.elapsedRealtime 或 uptimeMillis,Systrace 也有时间轴。需要你在抓取时记录手机当前时间(比如用 date 命令)来做标尺。
  • 理解关键线程和进程:至少要知道主线程(UI Thread)、Binder Thread、RenderThread、SurfaceFlinger 这些角色。

我曾经踩过的坑:有次一边 dump 一边抓 trace,结果忘记记下 dump 的精确时间,后面怎么也找不到对应分段。后来我强制自己在每步操作前敲一次 echo "---- $(date) ----" 到日志里,再也没丢过对齐点。

好了,这一章先到这。工具熟悉了,框架搭好了,接下来我们就要进入实战,先把 dumpsys 的几个核心服务翻个底朝天。