1. dumpsys 命令基础与队列概览
现象识别:队列拥堵的典型症状
当 Android 设备出现以下现象时,极可能是系统内部队列发生拥堵:
- 应用启动慢、界面滑动掉帧(卡顿)
- 按键无响应、触摸延迟超过 200ms
- 频繁 ANR(应用无响应)或系统服务超时
- Binder 调用超时(DeadObjectException)
- 多线程竞争导致 CPU 空转(高 IOWait)
此时需要借助 dumpsys 命令穿透至各服务内部,直接观察队列深度、等待线程数、处理耗时等关键指标。
数据采集:dumpsys 命令格式与常用参数
dumpsys 是 Android 调试桥(ADB)内置的系统状态转储工具。执行格式:
adb shell dumpsys [service] [options]
若不指定 service,则输出所有系统服务状态(文本量极大);生产中必须指定目标服务或使用过滤参数。
常用参数速查表
| 参数 / 选项 | 说明 | 典型使用场景 |
|---|---|---|
--help |
显示该服务的可用转储选项 | 首次排查不熟悉的服务 |
-t <timeout> |
设置等待转储完成的超时时长(秒) | 防止死锁服务阻塞 adb 会话 |
--pid <pid> |
仅转储指定进程的服务数据 | 聚焦某个应用或进程 |
--queue 或 -q |
部分服务支持仅输出队列状态(需查阅帮助) | 快速获取队列摘要 |
--threads |
输出线程及对应的等待队列信息 | 排查线程级阻塞 |
采集标准操作:
adb shell dumpsys -t 10 activity processes —— 限定超时 10 秒,转储 ActivityManager 的进程队列;
adb shell dumpsys input --queue —— 仅输出 Input 队列深度与等待事件;
adb shell dumpsys meminfo --package com.example —— 排查内存压力导致的队列堆积。
原因定位:dumpsys 输出结构速览与队列类型分类
dumpsys 输出由服务名称 + 缩进层级组成,队列状态通常出现在以下固定字段内:
- Binder 线程池状态:
Binder Thread States显示线程活跃数、等待数、处理延迟。 - Input 队列:
Input Dispatcher State含等待窗口、待分发事件数、每个事件排队时长。 - MessageQueue / Looper:
Main Looper或HandlerState显示消息延迟。 - 工作线程队列:如
AsyncTask线程池、HandlerThread等。 - 网络 / I/O 队列:
NetworkStats、Storage中的请求等待列表。
队列类型分类与排查要点
| 队列类型 | 典型服务 / 输出块 | 关键指标 | 判断规则 |
|---|---|---|---|
| Binder 线程池 | activity processes, meminfo 等 |
活跃线程数、等待线程数、最大线程数(默认 16) | 等待线程 ≥ 活跃线程 → 可能死锁或服务耗时长 |
| Input 分发队列 | input |
未处理事件数、等待时长(ms)、窗口阻塞标记 | 未处理事件持续增长 > 300ms → 输入卡顿 |
| Looper / MessageQueue | activity, window, 各 app |
待处理消息数、最早消息延迟、IdleHandler 数量 | 延迟 > 500ms 且消息数 > 50 → ANR 高危 |
| 线程池工作队列 | jobscheduler, netd |
队列容量、当前排队数、拒绝任务数 | 拒绝任务 > 0 → 需要扩大池大小或降低任务频率 |
判断故障树(初始层)
以下故障树适用于首次发现队列异常时快速定性:
条件1:dumpsys 输出中 “waiting threads” > 0
└→ 是 → Binder 线程池耗尽 → 检查服务端同步方法 / 死锁
└→ 否 → 检查 Input 队列 “pending events” > 100
└→ 是 → 窗口冻结或主线程阻塞 → 抓取 /proc/…/wchan
└→ 否 → 检查 MessageQueue 延迟 > 1s
└→ 是 → 应用主线程执行耗时任务 → 排查 Handler.post
└→ 否 → 采集基线对比
修复动作:基于队列状态的初步应对
本章仅建立认知框架,具体修复动作在后续章节展开。但可总结两条通用原则:
- 队列深度持续增长 → 优先检查是否存在竞态条件或长时间持有的锁。
- 等待时长突增 → 检查对应线程的当前调用栈(
kill -3 <pid>获取 traces.txt)。
复测:对比输出验证修复效果
执行修复后,再次执行相同 dumpsys 命令:
adb shell dumpsys -t 10 input --queue
adb shell dumpsys -t 10 activity processes
对比前后两次输出中队列深度、等待时长、线程状态等指标。若队列恢复正常基线,则问题解决;否则需进入更深层定位(查看日志、内核调度等)。
预防:建立队列状态监控基线
日常运维中,在设备空闲且无异常时执行一次全量 dumpsys,保存输出作为基线。重点记录:
- 各服务 Binder 线程池的活跃/等待比例
- Input 队列未处理事件数(通常为 0 或 ≤ 2)
- 主线程 Looper 消息延迟(应 < 50ms)
将基线写入自动化巡检脚本,当实时指标偏离基线超过 2σ 时触发告警,实现防患于未然。
本章核心概念关系图
本章要点自测
- 你能默写出
dumpsys命令采集 Input 队列和 Binder 线程池状态的完整命令行吗? - 请列举至少 3 种 Android 内部队列及其对应的关键指标。
- 当等待线程数超过活跃线程数时,故障树建议检查什么?
- 如何建立队列状态监控基线?每日巡检应关注哪些字段?