温馨提示×

如何排查ubuntu僵尸进程

小樊
41
2026-10-15 22:02:20
栏目: 智能运维

在 Ubuntu(以及其他 Linux 发行版)中,**僵尸进程(Zombie / Defunct Process)**是指已经结束运行、但其父进程还没有调用 wait() 系列函数来回收其退出状态的进程。

下面按「识别 → 排查 → 处理 → 预防」的顺序说明。


一、如何识别僵尸进程

1. 使用 ps 查看

ps aux | grep Z

或

ps -ef | grep defunct

典型特征:

  • 状态列为 Z
  • 命令中带有 <defunct>

示例:

user  12345  12340  0 10:00 ?  00:00:00 [myapp] <defunct>

说明:

  • 12345 是僵尸进程 PID
  • 12340 是其父进程 PID(PPID)

2. 查看系统僵尸进程数量

top

在顶部可以看到:

Tasks: 210 total,   1 zombie

二、定位父进程(关键)

僵尸进程不能直接 kill,必须处理其父进程。

ps -o pid,ppid,stat,cmd -p <僵尸PID>

或:

pstree -p | grep <僵尸PID>

找到 PPID 后:

ps -p <PPID> -o pid,cmd,stat

三、如何处理僵尸进程

✅ 正确做法

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

  • 如果是你自己写的程序:

    • 在父进程中调用 wait() / waitpid()
    • 或使用 signal(SIGCHLD, SIG_IGN)
  • 如果是服务程序:

# 重启父进程(服务)
systemctl restart <service>

方法 2:杀死父进程(谨慎)

⚠️ 会影响该父进程管理的所有子进程

kill -TERM <PPID>
# 或
kill -9 <PPID>

父进程死后,僵尸进程会被 init(PID 1)接管并自动回收。


❌ 错误做法

kill -9 <僵尸PID>   # 无效

僵尸进程已经“死”了,无法再被杀。


四、特殊情况处理

1. 父进程是 init(PID 1)

正常情况下 init 会自动回收,若出现僵尸:

  • 可能是 init 卡死(极少见)
  • 考虑重启系统

2. Docker / 容器中僵尸进程

  • 容器 PID 1 未正确处理 SIGCHLD
  • 解决:
    • 使用 dumb-init / tini
    • 或在 Dockerfile 中:
      ENTRYPOINT ["tini", "--", "your-app"]
      

五、常见原因与预防

常见原因

  • 父进程死循环,未调用 wait()
  • 父进程崩溃但未重启
  • 多线程程序中信号未正确处理

预防建议

  • 编写服务时正确处理子进程退出
  • 使用进程管理工具(systemd / supervisor)
  • 定期监控僵尸进程数量

六、快速排查命令合集

# 查看僵尸
ps aux | awk '$8 ~ /Z/'

# 查看僵尸及其父进程
ps -eo pid,ppid,stat,cmd | awk '$3 == "Z"'

# 统计僵尸数量
ps aux | awk '$8 ~ /Z/' | wc -l

如果你愿意,可以把 ps aux | grep Z 或 pstree 的输出贴出来,我可以帮你具体分析是哪一个程序导致的。

0 踩