温馨提示×

centos如何定位僵尸进程

小樊
45
2026-10-26 18:55:09
栏目: 智能运维

在 CentOS(以及其他 Linux 发行版)中,僵尸进程(Zombie / defunct 进程) 的本质是:进程已经退出,但父进程还没有调用 wait()/waitpid() 回收它的退出状态。僵尸进程不占 CPU、不占内存,但会占用 PID 表项。

下面按“发现 → 定位父进程 → 处理”来说明。


一、如何发现僵尸进程

1. 使用 ps 查看

ps -ef | grep defunct

或

ps aux | awk '$8 ~ /Z/'

僵尸进程在 STAT 列通常显示为:

Z   (zombie)

示例:

user  12345 12300  0 10:00 ?  00:00:00 [process] <defunct>

其中:

  • 12345:僵尸进程 PID
  • 12300:父进程 PPID(关键)

2. 使用 top

top

在任务统计区会看到:

Tasks: 210 total,   1 zombie

按 f 可以显示更多列,如 PPID、STAT。


3. 使用 /proc 精确检查

for p in /proc/[0-9]*; do
  if [ "$(cat $p/stat 2>/dev/null | awk '{print $3}')" = "Z" ]; then
    echo "Zombie PID: $(basename $p)"
  fi
done

二、如何定位僵尸进程的“罪魁祸首”(父进程)

僵尸进程无法直接 kill,必须处理它的父进程。

查看父进程

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

示例:

ps -o pid,ppid,stat,cmd -p 12345

输出:

PID   PPID  STAT CMD
12345 12300 Z    [process] <defunct>

→ 父进程是 12300


查看父进程信息

ps -p 12300 -o pid,ppid,cmd,stat

或:

cat /proc/12300/cmdline

三、如何处理僵尸进程

✅ 方法 1:让父进程回收(正确方式)

  • 如果是自己写的服务 / 程序 bug:
    • 修改代码,正确处理 SIGCHLD
    • 调用 wait() / waitpid()
  • 如果是 systemd / 服务管理问题:
    systemctl restart <服务名>
    

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

如果父进程是普通服务:

kill -TERM 12300
# 或
kill -9 12300

父进程死后:

  • 僵尸进程会被 init / systemd (PID 1) 接管
  • 由 PID 1 自动 wait() 回收
  • 僵尸消失 ✅

✅ 方法 3:父进程是 PID 1(少见但危险)

如果父进程是 1:

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

→ PPID = 1

说明:

  • init/systemd 没正确处理子进程
  • 不要 kill PID 1
  • 解决方式:
    • 升级 systemd
    • 排查是哪个 service 产生僵尸
    • 重启对应 service

四、常见产生僵尸进程的原因

原因 说明
父进程未 wait 子进程 最常见
忽略 SIGCHLD 错误写法
多线程程序中主线程退出 子线程变僵尸
第三方程序 bug Java / Python / C 服务
Docker / 容器 init 问题 容器内 PID 1 处理不当

五、快速排查模板(可直接用)

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

或一键脚本:

ps -eo pid,ppid,stat,cmd | awk '$3=="Z"{print "Zombie:",$1,"Parent:",$2}'

如果你愿意,可以把:

  • ps -ef | grep defunct
  • 或 top 的输出贴出来

我可以帮你具体定位是哪一个服务或程序导致僵尸进程。

0 踩