在 CentOS(以及其他 Linux 发行版)中,**僵尸进程(Zombie / defunct 进程)**的本质是:
子进程已经退出,但父进程还没有调用
wait()/waitpid()回收它,导致进程表中仍保留其退出状态。
下面从原因、常见场景、排查与解决办法几个方面说明。
exit())wait() / waitpid()Z(zombie)状态✅ 僵尸进程 不占 CPU、不占内存,只占用一个 task_struct 和 PID。
常见情况:
SIGCHLD 信号signal(SIGCHLD, SIG_IGN)(某些旧实现不会自动回收)wait如:
& 启动子进程但没 wait这些父进程活着,子进程频繁创建和退出 → 僵尸堆积。
fork() 方式启动子进程SIGSTOP此时子进程退出后无法被回收。
ps -ef | grep defunct
或:
ps -l
状态为 Z:
STAT Z
查看父子关系:
pstree -p | less
❌ 不能直接 kill 僵尸进程
kill -9 <zombie_pid> # 无效
因为:
SIGCHLDsignal(SIGCHLD, SIG_DFL);
或waitpid(-1, NULL, WNOHANG);
找到僵尸的父进程:
ps -o ppid= -p <zombie_pid>
然后重启该父进程:
systemctl restart xxx
# 或
kill -TERM <ppid>
父进程退出后:
init / systemd(PID 1)接管wait() 回收如果是自己写的服务:
Type=simplefork()| 场景 | 说明 |
|---|---|
| Java 程序 | 频繁 Runtime.exec() |
| Python | subprocess 未 wait() |
| Shell 脚本 | cmd & 没 wait |
| cron | 脚本 fork 后退出 |
| 容器 / 宿主机混用 | PID namespace 问题 |
✅ 少量僵尸:
❌ 大量僵尸(几千+):
systemd 管理fork()ps -eo stat | grep Z | wc -l
如果你愿意,可以贴出:
ps -ef | grep defunctpstree -p我可以帮你精确定位是哪个程序导致僵尸进程。