温馨提示×

ubuntu 如何清理僵尸进程

小樊
32
2026-08-23 19:11:33
栏目: 智能运维

在 Ubuntu(以及所有 Linux 系统)中,僵尸进程(Zombie Process)本质上是已经结束但还没有被父进程回收的进程。它们不占用 CPU 或内存,但会占用进程号(PID)。

重点结论
僵尸进程不能直接被 kill 掉,只能通过 让它的父进程回收它让父进程退出 来清除。


一、什么是僵尸进程?

僵尸进程状态为 Z(Zombie):

ps aux | grep 'Z'

或:

ps -eo pid,ppid,stat,cmd | grep 'Z'

示例:

PID   PPID  STAT CMD
1234  1000  Z    [myapp] <defunct>
  • STAT=Z → 僵尸
  • <defunct> → 已死但未回收

二、为什么会产生僵尸进程?

常见原因:

  1. 父进程没有调用 wait() / waitpid()
  2. 父进程逻辑有 bug
  3. 父进程卡死 / 阻塞
  4. 父进程是 shell 脚本,未正确处理子进程

三、正确清理僵尸进程的方法(重点)

✅ 方法 1:让父进程回收(推荐)

找到僵尸进程的 父进程 PPID

ps -eo pid,ppid,stat,cmd | grep Z

假设:

PID   PPID
1234  1000

然后:

kill -SIGCHLD 1000

如果父进程正常,它会回收子进程。


✅ 方法 2:重启 / 终止父进程(最常用)

如果父进程不处理 SIGCHLD:

kill 1000

或强制:

kill -9 1000

一旦父进程退出:

  • 僵尸进程会被 init(或 systemd,PID 1)接管
  • init 会自动回收

✅ 僵尸进程随后消失


✅ 方法 3:重启相关服务(生产环境推荐)

如果是服务产生的僵尸:

systemctl restart your-service

例如:

systemctl restart nginx
systemctl restart php-fpm

四、❌ 错误做法(无效)

kill -9 僵尸PID

无效,因为进程已经死了,只是残留 PCB。


五、如何防止僵尸进程?

✅ 正确做法(开发角度)

1️⃣ 父进程调用 wait()

wait(NULL);

或:

waitpid(pid, NULL, 0);

2️⃣ 忽略 SIGCHLD(不推荐但可用)

signal(SIGCHLD, SIG_IGN);

适用于不关心子进程退出状态的情况


3️⃣ fork + 两次 fork(守护进程常用)

父 -> 子 -> 孙
子立刻退出
孙被 init 接管

六、快速排查脚本(实用)

ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'

七、总结(速查表)

场景 解决方案
单个僵尸 kill 父进程
服务产生僵尸 systemctl restart
父进程卡死 kill -9 父进程
防止僵尸 wait / SIGCHLD
kill 僵尸进程 ❌ 无效

如果你愿意,可以把你的 ps -ef 输出具体服务名 发出来,我可以帮你精确判断该杀哪个进程。

0