1. 课程导入
Android 系统服务是整机运行的中枢:ActivityManagerService、WindowManagerService、PackageManagerService、InputManagerService、SurfaceFlinger、SystemServer 中的各类 Binder 服务,共同支撑应用启动、窗口绘制、输入分发、权限校验与进程调度。一旦某个系统服务出现阻塞、崩溃、死锁或资源泄漏,表现往往不是"某个应用报错",而是整机卡顿、黑屏、重启、ANR 甚至无法开机。因此,系统服务稳定性调试的核心,不是"改一行代码让日志消失",而是建立一套从现象到根因的可复现、可度量、可验证的排查能力。
一、学习目标:从"看日志"到"建模型"
本课程面向已经具备 Android 应用开发或系统开发基础、希望深入系统稳定性领域的工程师。完成学习后,应达到以下目标:
- 能区分系统服务稳定性问题的四类典型现象:崩溃(Crash)、无响应(ANR/Block)、异常重启(Reboot/Watchdog)、性能劣化(卡顿、掉帧、内存增长)。
- 能读懂 SystemServer 启动流程、Binder 通信模型、Watchdog 检测机制与 AMS/WMS 关键锁结构。
- 能独立完成一次系统服务卡死的现场抓取:logcat、dumpsys、traces、tombstone、dropbox、/data/anr 等。
- 能使用 Systrace/Perfetto、simpleperf、GDB、Binder 调试节点等工具定位到具体线程与调用栈。
- 能针对死锁、锁竞争、Binder 超时、内存泄漏等典型根因给出修复方案并设计回归验证。
二、核心概念:先建立系统服务的"运行模型"
系统服务稳定性问题之所以难,是因为它跨越了 Java 层、Native 层与内核层。理解下面几个概念,是后续所有调试工作的前提。
SystemServer 与系统服务生命周期。SystemServer 由 Zygote fork 而来,依次启动引导服务、核心服务和其他服务。服务启动顺序决定了依赖关系,也决定了"谁先卡住会拖垮谁"。
Binder 通信与线程池。应用通过 Binder 调用系统服务,服务端由 Binder 线程池处理请求。当服务端持锁时间过长,Binder 线程被占满,调用方就会阻塞,最终触发 ANR 或 Binder 超时。
Watchdog 与系统重启。Watchdog 周期性检查关键服务与监控线程是否按时"喂狗"。一旦超时,会抓取 traces 并触发系统重启,这是系统服务卡死最典型的兜底机制。
锁与并发。AMS、WMS、PMS 内部大量使用 synchronized 与各类 Lock。锁顺序不一致会死锁,锁粒度过大会造成竞争,这是系统服务稳定性问题的头号根因。
现象(卡顿/ANR/重启) → 现场(日志/traces/dumpsys) → 线程与锁(调用栈/锁持有) → 根因(死锁/竞争/泄漏/超时) → 修复 → 回归验证
三、整体知识框架与实战路线图
下图给出本课程的整体知识框架:左侧是问题现象入口,中间是调试工具与数据来源,右侧是根因分类与修复方向,底部是贯穿全程的实战路线。
四、典型场景与误区复盘
以一个真实场景为例:某设备在连续使用 2 小时后出现整机卡顿,随后 Watchdog 触发重启。初步 logcat 只能看到"Watchdog: Blocked in handler on ActivityManager",但看不到根因。正确做法是:先取 /data/anr/traces.txt 与 dropbox 中的 watchdog 记录,确认被阻塞的线程;再用 dumpsys activity 与 Binder 调试节点确认是否有服务端长持锁;最后结合 Systrace 观察锁竞争窗口。常见误区如下:
| 误区 | 表现 | 正确做法 |
|---|---|---|
| 只看 logcat 就下结论 | 日志只显示"Blocked",误判为应用问题 | 结合 traces、dumpsys、dropbox 交叉验证 |
| 把 ANR 当成应用单方问题 | 忽略服务端 Binder 线程被占满 | 同时检查调用方与服务端线程栈 |
| 用加大超时"掩盖"问题 | 卡顿依旧,只是不报错 | 定位长持锁点,缩短临界区 |
| 修复后不做长稳回归 | 问题在特定压力下复现 | Monkey + 长稳 + 指标对比 |
五、常用命令速查
# 抓取系统服务与线程状态
adb shell dumpsys activity services
adb shell dumpsys window
adb shell dumpsys package
# 抓取 ANR / Watchdog traces
adb pull /data/anr/traces.txt
adb shell dumpsys dropbox --print system_app_anr
# 抓取 Binder 与锁信息
adb shell cat /sys/kernel/debug/binder/state
adb shell cat /proc/<pid>/task/<tid>/stack
# 性能与调度分析
adb shell atrace -t 10 -b 8000 gfx view binder_driver
adb shell simpleperf record -p <pid> --duration 10