在 Ubuntu(以及其它 Linux 发行版)里,**僵尸进程(zombie / defunct process)**的本质是:
子进程已经结束运行,但父进程还没有调用
wait()/waitpid()来回收它的退出状态。
也就是说,僵尸进程不是“死不掉”,而是**“死透了但没人收尸”**。
这是最常见原因:
exit()wait() / waitpid()Z(zombie)示例(C):
pid_t pid = fork();
if (pid == 0) {
exit(0); // 子进程退出
}
// 父进程什么都不做
此时子进程就是僵尸。
即使父进程“打算”回收,也可能:
SIGCHLDsignal(SIGCHLD, SIG_IGN);
在某些 UNIX 上会防止僵尸,但在 Linux 上不一定可靠,不推荐用于防止僵尸。
如:
fork父进程来不及回收 → 僵尸堆积
init / systemd 接管但若中间层父进程异常,仍可能短期僵尸。
常见于:
Z查看方式:
ps -ef | grep defunct
top
看到:
app 1234 1200 0 10:00 ? 00:00:00 [app] <defunct>
wait() / waitpid()sigaction 处理 SIGCHLDsystem() / popen() 等已封装函数# 找到僵尸的父进程 PPID
ps -o pid,ppid,stat,cmd -C xxx
# 重启父进程(最常见有效手段)
systemctl restart xxx
⚠️ 不要 kill 僵尸本身,无效
❌ 僵尸会吃内存
✅ 不会,只保留极小结构体
❌ kill -9 能杀僵尸
✅ 不行,它已经“死”了
❌ 僵尸一定是病毒
✅ 大多数是程序 bug 或设计问题
如果你愿意,可以:
ps / top 输出我可以帮你精确定位原因并给修复方案。