linux的僵尸进程

2019-06-04

什么是僵尸进程?

我们启动一个程序,开始我们的任务,然后等任务结束了,我们就停止这个进程。 进程停止后, 该进程就会从进程表中移除。
但是,有时候有些程序即使执行完了也依然留在进程表中。那么,这些完成了生命周期但却依然留在进程表中的进程,我们称之为 “僵尸进程”。

它们是如何产生的?

当你运行一个程序时,它会产生一个父进程以及很多子进程。 所有这些子进程都会消耗内核分配给它们的内存和 CPU 资源。这些子进程完成执行后会发送一个 Exit 信号然后死掉。这个 Exit 信号需要被父进程所读取。父进程需要随后调用 wait 命令来读取子进程的退出状态,并将子进程从进程表中移除。若父进程正确第读取了子进程的 Exit 信号,则子进程会从进程表中删掉。但若父进程未能读取到子进程的 Exit 信号,则这个子进程虽然完成执行处于死亡的状态,但也不会从进程表中删掉。

那么如何找出僵尸进程呢?

打开终端并输入下面命令:

ps aux | grep Z

会列出进程表中所有僵尸进程的详细内容。

处理方法一:

正常情况下我们可以用 SIGKILL 信号来杀死进程,但是僵尸进程已经死了, 你不能杀死已经死掉的东西。 因此你需要输入的命令应该是

kill -s SIGCHLD pid

将这里的 pid 替换成父进程的进程 id,这样父进程就会删除所有以及完成并死掉的子进程了。

许多程序写的不是那么好,无法删掉这些子僵尸(否则你一开始也见不到这些僵尸了)。 因此确保删除子僵尸的唯一方法就是杀掉它们的父进程。

处理方法二

查看僵尸进程

ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'

命令注解:
-A 参数列出所有进程
-o 自定义输出字段 我们设定显示字段为 stat(状态), ppid(进程父id), pid(进程id),cmd(命令)这四个参数
因为状态为 z或者Z的进程为僵尸进程,所以我们使用grep抓取stat状态为zZ进程

输出:

Z 10674 24201 [kontainer-engin]

这时,我们可以使用kill -HUP 10674来杀掉这个僵尸进程

kill -HUP 10674

运行后,可以再次运行ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'来确认是否已经将僵尸进程杀死
如果kill 子进程的无效,可以尝试kill 其父进程来解决问题

批量处理:

ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9

kill后出现问题的解决办法:

场景:jps 报process information unavailable解决方法

jps时出现如下信息:
22162– process information unavailable

解决办法:
进入tmp目录,删除该目录下名称为hsperfdata_{username}的文件夹

相关链接:
https://blog.csdn.net/juS3Ve/article/details/81125530


标题:linux的僵尸进程
作者:fish2018
地址:http://www.devopser.org/articles/2019/06/04/1559617932598.html