在 CentOS(以及其他 Linux 系统)中,僵尸进程(Zombie / defunct)本质上是已经结束但父进程还未回收其资源的进程。它本身不占用 CPU、内存,只是占用一个 PID 和进程表项。
ps -ef | grep defunct
# 或
ps aux | awk '$8 ~ /Z/'
状态为 Z 的就是僵尸进程。
❌ 不能直接 kill 僵尸进程
kill -9 <pid> # 对僵尸进程无效
因为进程已经死了,只是父进程没“收尸”。
ps -ef | grep defunct
示例:
user 1234 1200 0 10:00 ? 00:00:00 [xxx] <defunct>
这里 1200 是父进程 PID
kill -9 1200
⚠️ 注意:
如果是你自己的程序(C / Java / Python):
SIGCHLDwait() / waitpid()例如 Python:
import signal, os
def reap_children(signum, frame):
while True:
try:
pid, _ = os.waitpid(-1, os.WNOHANG)
if pid == 0:
break
except ChildProcessError:
break
signal.signal(signal.SIGCHLD, reap_children)
systemctl restart <服务名>
例如:
systemctl restart nginx
systemctl restart docker
如果父进程是 1:
systemctl daemon-reexec
ps -eo ppid,stat | grep Z | awk '{print $1}' | sort | uniq -c
看是哪个父进程在“批量制造”僵尸。
✅ 正确写多进程程序
✅ 使用 systemd 管理服务
✅ 避免 fork 后不 wait
✅ 使用线程代替进程(如可行)
僵尸进程杀不掉,只能让父进程回收或杀父进程。
如果你愿意,可以把 ps -ef | grep defunct 的输出贴出来,我可以帮你具体分析该杀哪个进程。