进程列表获取与筛选
现象识别
当设备出现以下现象时,需要第一时间获取进程列表:
- 耗电异常:待机状态电池曲线陡降,系统 Top 耗电排行中“Android 系统”或“媒体服务器”占比过高
- 设备发热:未运行大型游戏时机身持续高温,CPU 占用率长期 > 50%
- 界面卡顿 / ANR:应用无响应提示频繁出现,或触控延迟明显
- 后台自启 / 相互唤醒:某应用被强杀后自动复活,或全家桶链式启动
- 隐私/安全怀疑:发现陌生包名、高权限进程或子进程异常
排查切入点:先通过系统设置 → 开发者选项 → 正在运行的服务 做初步列表,再使用 adb shell 命令精确采集。
数据采集
核心命令包括 ps 和 top,以及辅助的 pidof、pgrep。采集时需关注进程名、PID、UID、内存和 CPU 占用。
1. ps 命令
列出当前所有进程的瞬间快照,命令格式及常用参数:
adb shell ps # 默认 SYSVR4 风格(USER PID PPID … NAME)
adb shell ps -A # 显示所有进程(Android 7+)
adb shell ps -T # 显示线程(轻量级进程)
adb shell ps -eo pid,ppid,uid,cpu,args --sort=-%cpu # Linux 原生格式,按 CPU 降序
输出列含义:
| 列 | 含义 |
|---|---|
| USER | 运行该进程的 UID 名称(如 u0_a15) |
| PID | 进程唯一 ID |
| PPID | 父进程 ID |
| CPU | 瞬间 CPU 占用百分比(仅部分格式) |
| NAME / COMMAND | 进程名或可执行文件路径 |
2. top 命令
动态刷新进程资源占用,适合定位瞬时高负载进程:
adb shell top -n 1 -b # 单次批处理输出(非交互)
adb shell top -d 2 -n 5 # 每 2 秒采样一次,共 5 次
adb shell top -o -%CPU # 按 CPU 占用排序(按需调整参数)
常见输出字段:PID、PR、CPU%、S(状态)、VIRT、RES、NAME。
3. 通过包名查询 PID
adb shell pidof com.example.app # 直接返回 PID
adb shell ps | grep com.example.app # 字符串匹配
4. 通过 UID 筛选
先获取应用 UID:
adb shell dumpsys package com.example.app | grep userId=
adb shell pm list packages -U | grep com.example.app
然后用 UID 过滤进程:
adb shell ps | grep u0_a15 # u0_a15 是举例 UID
注意:不同 Android 版本的 ps 输出格式有差异(SYSVR4 / BSD / Linux raw)。建议统一使用
ps -A -o PID,UID,CPU,ARGS(Linux 原生格式)以获得稳定列顺序。
原因定位
通过采集的进程列表,使用以下排查表判断异常进程:
| 异常特征 | 可疑指标 | 常见原因 |
|---|---|---|
| CPU 占用持续 > 40% | top 中 %CPU 列长期高居不下 | 应用死循环、渲染过重、恶意挖矿 |
| 内存占用异常大 | VIRT 或 RES 远超同类应用 | 内存泄漏、数据库缓存巨大、Bitmap 未释放 |
| 进程名与包名不符 | ps 显示 system_server 但包名是第三方 | 进程注入、伪装系统进程 |
| 父进程为 Zygote 但 UID 异常 | PPID=1 但 USER=root 且未授权 | Root 提权或恶意应用 |
| 进程数量成倍增长 | 同一包名下出现多个 PID | 多进程架构失控、相互唤醒循环 |
| 无界面进程长期存活 | UID=u0_xxx 但无前台 Activity | 定时任务、常驻 Service、推送保活 |
故障树判断逻辑:
1. 是否系统进程(UID root/system/radio)?
├─是 → 检查 kernel 或 hal 层,关注 watchdog、surfaceflinger、audioserver
└─否 → 进入第 2 步
2. 该进程是否与前台应用相关?
├─是 → 检查该应用自身的 Activity 生命周期、Service 泄漏
└─否 → 进入第 3 步
3. 该进程是否存在频繁唤醒锁(wake lock)?
├─是 → 检查 PowerManager.WakeLock 泄漏或第三方 SDK 保活
└─否 → 进入第 4 步
4. 进程名是否包含 ams、system、input 等系统关键词?
├─是 → 可能系统服务异常,收集 anr trace / bugreport
└─否 → 标记为可疑后台进程,采集完整堆栈
修复动作
- 强制停止:
adb shell am force-stop <package_name> - 杀死指定 PID:
adb shell kill -9 <PID>(注意 system 级进程谨慎操作) - 卸载异常应用:
adb uninstall <package_name> - 清除应用数据:
adb shell pm clear <package_name> - 重启系统服务:针对 system_server 等异常,可尝试
adb shell am restart(部分设备支持)或直接 reboot
极端情况处理:若进程无法 kill(如 init 进程或 mediaserver),需要
adb root 后 adb shell stop 或 adb shell setprop ctl.stop <service_name>,再重新启动。
复测
- 再次执行
adb shell top -n 1 -b | grep <package>确认进程已被清除 - 观察 10 分钟:
adb shell top -d 10 -n 6 -b > /tmp/cpu_log.txt检查是否复活 - 检查关联进程:
adb shell ps -A | grep <package>确保全家桶未拉起 - 验证功能:启动目标应用,确认正常使用且无异常后台行为
预防
| 预防措施 | 操作/命令 |
|---|---|
| 监控 CPU/内存基线 | 使用 adb shell dumpsys cpuinfo 定期采样;脚本告警 |
| 限制后台运行 | 开发者选项 → 后台进程限制 / 按需选择“不允许” |
| 审查第三方 SDK 保活行为 | 反复抓取 ps + top 对比前后关联进程链 |
| 使用 JobScheduler 代替 Service | 代码审计,确保长运行 Service 改为 JobScheduler 或 WorkManager |
| 定期扫描异常 UID | 编写脚本:ps -A | awk '$2!="0" && $1!="root" && $1!="system" && $1!="radio" {print}' |