温馨提示×

debian怎么排查僵尸进程

小樊
40
2026-10-02 00:29:35
栏目: 智能运维

在 Debian(以及其他 Linux 发行版)上排查僵尸进程(Zombie / defunct 进程),可以按下面的思路逐步来。


一、什么是僵尸进程

僵尸进程是已经结束运行,但父进程还没有调用 wait() 回收它的进程。

  • 状态通常显示为 Z
  • 不占用 CPU、内存,只占用一个 PID 和进程表项
  • 大量僵尸进程会导致 PID 耗尽

二、查看僵尸进程

1. 使用 ps

ps -ef | grep defunct

或

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

示例输出:

 PID  PPID STAT CMD
1234  567   Z    [xxx] <defunct>

2. 使用 top

top

看右上角:

Tasks: 210 total,   1 running, 208 sleeping,   0 stopped,   1 zombie

三、找到僵尸进程的“元凶”(父进程)

关键看 PPID(父进程 ID)

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

例如:

 PID  PPID STAT CMD
1234  567  Z    [myapp] <defunct>

说明 PID 567 是有问题的父进程。


四、分析父进程为什么没回收

常见原因:

  1. 父进程 bug

    • 没有正确处理 SIGCHLD
    • 没有调用 wait() / waitpid()
  2. 父进程卡死 / 死锁

    • 父进程本身处于 D 状态(不可中断睡眠)
  3. 服务异常

    • Java / Python / C++ 程序异常
    • 容器或守护进程异常

查看父进程状态:

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

如果父进程是:

  • D:IO 卡死(磁盘/网络)
  • S 但长期不回收:代码问题

五、常见处理方式

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

systemctl restart 服务名

或

kill -TERM 567

⚠️ 不能直接 kill 僵尸进程,它已经“死”了

✅ 方法 2:让父进程回收(不推荐手动)

向父进程发送 SIGCHLD:

kill -CHLD 567

(仅对设计良好的程序有效)

✅ 方法 3:父进程是 init(PID 1)

如果是:

PPID = 1

说明父进程已退出但未被回收(极少见)

可尝试:

systemctl daemon-reexec

六、防止僵尸进程反复出现

1. 程序层面

  • 正确处理子进程退出
  • 使用 signal(SIGCHLD, SIG_IGN)(不推荐所有场景)
  • 或使用 waitpid(-1, NULL, WNOHANG)

2. 系统监控

# 查看僵尸数量
ps -eo stat | grep Z | wc -l

可加入:

  • Zabbix
  • Prometheus node_exporter
  • 自定义 cron 报警

七、快速排查清单(总结)

# 1. 看僵尸
ps -eo pid,ppid,stat,cmd | awk '$3=="Z"'

# 2. 看父进程
ps -o pid,ppid,stat,cmd -p <PPID>

# 3. 重启父进程
systemctl restart <service>

# 4. 确认
ps -eo stat | grep Z | wc -l

如果你愿意,可以把 ps 输出贴出来,我可以帮你具体分析是哪个服务或程序导致的。

0 踩