如果不清除僵尸状态有什么问题吗?


18

我有生产部门,其中Java进程已成为Zombie,并在那里停留了一段时间。如果重新启动设备,则将其清除。但是,该单元未重新启动,并且另一个Java进程已启动并正在运行。如果这个僵尸状态不清除就不会有问题吗?它会以任何方式(性能或缓慢性)受到影响吗?

Answers:


22

僵尸进程不会对性能或速度造成任何影响,因为僵尸进程不会消耗任何系统资源。

注意:- 实际上,它仍然使用PID(资源有限),并且仍分配进程的内核数据结构。通常,这无关紧要,但是在内存非常有限的系统上,内核内存的使用可能非常重要。

僵尸进程引起的问题

每个僵尸进程都保留其进程ID。Linux系统有进程ID的数量有限- 32767默认情况下在32位systems.If僵尸以非常快的速度正在积累,现有的PID整池最终将成为分配给僵尸进程,防止其他进程启动。

注意:在64位系统上,您可以增加最大PID,请参阅/unix//a/16884/170373

但是,几个僵尸进程没有问题-尽管它们确实表明系统上的父进程存在错误。

说明:

当一个进程在Linux上死亡时,它不会立即从内存中全部删除-它的进程描述符保留在内存中。

进程的状态变为,EXIT_ZOMBIE并通过SIGCHLD信号通知其父进程其子进程已死亡。

然后,假定父进程执行wait()系统调用以读取死进程的退出状态和其他信息。这允许父进程从无效进程中获取信息。调用wait()之后,僵尸进程将从内存中完全删除。

这通常很快发生,因此您不会在系统上看到僵尸进程的堆积。但是,如果父进程的编程不正确,并且从不调用wait(),则其僵尸子进程会一直停留在内存中,直到被清理干净为止。

解析度:

您无法杀死僵尸进程,就像可以通过SIGKILL信号杀死正常进程一样-僵尸进程已经死亡。

杀死僵尸的一种方法是将SIGCHLD信号发送到父进程。该信号告诉父进程执行wait()系统调用并清理其僵尸子进程。使用kill命令发送信号,将以下命令中的pid替换为父进程的PID:

kill -s SIGCHLD pid

当创建僵尸的进程结束时,init会继承僵尸进程并成为其新父进程。(init是在引导时在Linux上启动的第一个进程,并分配了PID1。)

注意:-从Linux 3.4开始,进程可以使用PR_SET_CHILD_SUBREAPER选项发出prctl()系统调用,结果,它们(而不是进程1)将成为其孤立后代进程的父级。请参阅:https//unix.stackexchange.com/a/177361/5132  

然后,INIT执行wait()系统调用以清理其僵尸子级,因此init将缩短僵尸的工作时间。您可以在关闭父进程后重新启动它。


wait()本身是否有可能失败?
拉维

3
在64位系统上,您可以增加最大PID,请参见unix.stackexchange.com/a/16884/170373
ilkkachu

1
关于重做的部分也是错误的。 unix.stackexchange.com/a/177361/5132 具有讽刺意味的是,使程序无法正常运行会导致长期的僵尸进程。
JdeBP '18年

2
当现在是僵尸的进程死亡时,父级将已经收到SIGCHLD。
安赫尔

2
严格来讲,不使用资源是不正确的。它仍在使用PID(资源有限),并且仍为进程分配内核数据结构。通常,这无关紧要,但是在内存非常有限的系统上,内核内存的使用可能非常重要。
奥斯汀·海默加恩

6

通常,僵尸不是一个大问题。它们是一个“死”进程,它不占用CPU时间,并且在死之前,该进程释放任何分配的内存。他们实际占用的唯一资源是您的进程列表中的一个条目。根据您的系统,您可以具有最大允许的线程数,而僵尸程序可以无缘无故地使您更快地达到此限制。

但是:僵尸通常是由于错误的/混乱的代码而出现的,程序员在其中忘记检查其子进程的状态。这可能是故意的,但通常不是。错误/错误的代码通常还会以错误的 特殊方式处理内存,并且释放某些已分配的资源。在这种情况下,这些资源将一直分配给僵尸,直到僵尸被完全终止。

编辑:如果该进程是一个Java程序,未释放的内存应该不成问题,因为Java垃圾收集器会处理所有事情。


3
实际上,不是提要内存并不是大多数操作系统都支持所有语言的问题。系统会为父进程释放除极少量外的所有内存。
瓦尔说恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.