在 Debian(以及其他 Linux 发行版)上排查僵尸进程(Zombie / defunct 进程),可以按下面的思路逐步来。
僵尸进程是已经结束运行,但父进程还没有调用 wait() 回收它的进程。
Zpsps -ef | grep defunct
或
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'
示例输出:
PID PPID STAT CMD
1234 567 Z [xxx] <defunct>
toptop
看右上角:
Tasks: 210 total, 1 running, 208 sleeping, 0 stopped, 1 zombie
关键看 PPID(父进程 ID)
ps -o pid,ppid,stat,cmd -p <僵尸PID>
例如:
PID PPID STAT CMD
1234 567 Z [myapp] <defunct>
说明 PID 567 是有问题的父进程。
常见原因:
父进程 bug
SIGCHLDwait() / waitpid()父进程卡死 / 死锁
D 状态(不可中断睡眠)服务异常
查看父进程状态:
ps -o pid,ppid,stat,cmd -p 567
如果父进程是:
D:IO 卡死(磁盘/网络)S 但长期不回收:代码问题systemctl restart 服务名
或
kill -TERM 567
⚠️ 不能直接
kill僵尸进程,它已经“死”了
向父进程发送 SIGCHLD:
kill -CHLD 567
(仅对设计良好的程序有效)
如果是:
PPID = 1
说明父进程已退出但未被回收(极少见)
可尝试:
systemctl daemon-reexec
signal(SIGCHLD, SIG_IGN)(不推荐所有场景)waitpid(-1, NULL, WNOHANG)# 查看僵尸数量
ps -eo stat | grep Z | wc -l
可加入:
# 1. 看僵尸
ps -eo pid,ppid,stat,cmd | awk '$3=="Z"'
# 2. 看父进程
ps -o pid,ppid,stat,cmd -p <PPID>
# 3. 重启父进程
systemctl restart <service>
# 4. 确认
ps -eo stat | grep Z | wc -l
如果你愿意,可以把 ps 输出贴出来,我可以帮你具体分析是哪个服务或程序导致的。