温馨提示×

centos为何出现僵尸进程

小樊
46
2026-09-09 07:30:50
栏目: 智能运维

在 CentOS(以及所有 Linux 系统)中,**僵尸进程(Zombie Process)**的本质原因是:

子进程已经结束,但父进程没有回收它的退出状态

下面从原理、常见原因、排查和解决方法几个方面说明。


一、什么是僵尸进程

  • 子进程调用 exit() 结束
  • 内核保留其 进程号(PID)、退出码等少量信息
  • 父进程必须通过 wait() / waitpid() 读取这些信息
  • 在父进程回收之前,子进程在 ps 中显示为:
    STAT = Z
    

示例:

ps -ef | grep defunct

二、CentOS 中僵尸进程出现的常见原因

1️⃣ 父进程未正确处理 SIGCHLD

父进程:

  • 忽略了 SIGCHLD
  • 或没有调用 wait()

例如:

signal(SIGCHLD, SIG_IGN);  // 可能导致僵尸

2️⃣ 父进程忙,没空回收子进程

  • 父进程是单线程
  • 在密集计算中,没机会 wait()

3️⃣ 父进程自己阻塞 / 卡死

  • 父进程死锁
  • 父进程在 I/O 上阻塞
  • 父进程异常(但还没退出)

4️⃣ 程序 bug(最常见)

  • fork() 后忘记 wait()
  • 异常路径没回收子进程

5️⃣ 服务设计问题

例如:

  • Java / Python 程序中频繁 subprocess.Popenwait()
  • shell 脚本中 cmd & 但父脚本长期运行

6️⃣ 父进程是 init(PID 1)但系统异常

  • 正常情况下 init 会回收孤儿进程
  • 如果 PID 1 异常(容器环境常见),僵尸无法回收

三、僵尸进程的危害

✅ 不占 CPU
✅ 不占内存(除 task_struct)
占用 PID 资源

⚠️ 如果僵尸太多:

  • PID 用尽
  • 无法创建新进程
  • 系统变慢甚至不可用

四、如何排查僵尸进程

1️⃣ 查看僵尸进程

ps -ef | grep defunct

ps -eo pid,ppid,stat,cmd | awk '$3=="Z"'

2️⃣ 查看僵尸数量

ps -eo stat | grep Z | wc -l

3️⃣ 找父进程

pstree -p | grep -A5 -B5 <僵尸PID>

五、如何解决僵尸进程

✅ 正确做法(推荐)

1️⃣ 修复父进程代码

  • 使用 wait() / waitpid()
  • 或设置:
signal(SIGCHLD, SIG_DFL);

2️⃣ 重启父进程

kill -TERM <父进程PID>

僵尸会随父进程退出被 init 回收


❌ 错误做法(无效)

kill -9 <僵尸PID>

❌ 僵尸已是死进程,无法被 kill


六、CentOS 特殊场景

容器中(Docker / K8s)

  • PID 1 不是 systemd
  • 僵尸只能由 PID 1 回收
  • 解决:
    • 使用 tini
    • dumb-init

七、总结一句话

CentOS 出现僵尸进程,不是系统问题,而是“父进程没回收子进程”

如果你愿意,可以:

  • ps 输出
  • 或说明是什么服务(Java / Nginx / Shell / Docker)

我可以帮你精准定位原因。

0