僵尸进程数量在top第二行zombie字段中显示,非零即存在;大于5需警觉,超20基本表明父进程回收异常。该数值是内核实时统计,比ps过滤更可靠。

系统是否存在大量僵尸进程,直接看 top 第二行的 zombie 数字就行——只要它非零,就说明有;大于 5 就该警觉,超过 20 基本可以判定父进程存在回收缺陷或已卡死。
用 top 快速确认僵尸数量是否异常
top 是最轻量、最实时的方式,无需解析输出、不依赖权限,连 root 都不用:
- 运行
top,紧盯第二行类似Tasks: 142 total, 1 running, 139 sleeping, 0 stopped, 3 zombie中的数字 - 该值稳定为 0 是健康状态;持续增长(比如每分钟+1)说明父进程完全没在回收
- 注意:这个数字是内核统计的实时值,比
ps管道过滤更可靠,因为不涉及文本匹配误判 - 别被
top进程列表里偶尔闪过的Z状态迷惑——那是瞬时状态,真正要盯的是汇总行的zombie计数
用 ps 精准提取所有 Z/z 状态进程并计数
当需要脚本化监控或排查具体是哪些 PID 在堆积时,必须用字段锚定的 ps 命令,否则极易漏判或误抓:
- 正确命令:
ps -eo stat,pid,ppid,comm | grep '^[Zz]'——^锚定行首,[Zz]兼容大小写,只匹配真实状态列 - 错误写法:
ps aux | grep Z会把命令名含Z的进程(如gzip、zip)全抓出来 - 统计总数(用于告警阈值):
ps -eo stat= | grep -c '^[Zz]',输出纯状态列再计数,无干扰 - 如果返回空,但
top显示有 zombie,大概率是内核版本输出小写z,而你只搜了大写Z
查清是不是真僵尸,还是误判成 D/Z 的不可中断进程
很多“疑似僵尸”其实是 D 状态(不可中断睡眠),比如卡在坏磁盘 I/O 或 NFS 挂载点上,处理方式完全不同:
-
Z进程:零 CPU、零内存占用,ps输出cmd列常为[xxx],kill -9返回No such process -
D进程:仍占内存、可能占 CPU,ps输出cmd列是完整命令,kill -9会阻塞住(卡在信号队列),不会立刻返回 - 快速区分:
ps -eo pid,stat,rss,pcpu,comm | awk '$2 ~ /^[Zz]$/ {print}'—— 如果rss和pcpu全是 0,基本可断定是真僵尸
为什么不能只看 ps aux | grep defunct
是 ps 的格式化字符串,并非内核字段,不同发行版、不同 ps 实现(procps-ng vs busybox)可能不输出,或输出位置不固定:
- 某些容器环境或精简系统中,
ps根本不显示,只显示Z状态 -
grep defunct会漏掉没有该字符串但状态确实是Z的进程 - 真正唯一可信的标识只有
STAT列的首字符,它由内核直接提供,不受用户态格式影响
真正麻烦的不是发现僵尸,而是发现一堆僵尸却找不到对应父进程在哪儿——比如父进程 PID 已被复用,或者父进程是 systemd 下某个瞬时服务单元,PPID 指向的是一个早已退出的临时进程。这种情况下,ps -o ppid= -p 返回的 PPID 可能已经无效,得结合 /proc/ 看它是否还存活。











