我有一个生产单元,其中 Java 进程已成为僵尸,并且现在在那里停留了一段时间。如果设备重新启动,则它将被清除。但是,该单元并未重新启动,并且另一个 java 进程已启动并正在运行。如果这个僵尸状态没有清除它就保持原样,会有什么问题吗?它会以任何方式(性能或缓慢)产生影响吗?
小智 23
僵尸进程不会对性能或缓慢产生任何影响,因为僵尸进程不会占用任何系统资源。
注意:- 实际上,它仍在使用 PID(这是一种有限的资源),并且仍在分配进程的内核数据结构。通常,这无关紧要,但在内存非常有限的系统上,内核内存使用量可能很大。
僵尸进程引起的问题
每个僵尸进程都保留其进程 ID。Linux系统有进程ID的数量有限- 32767默认情况下在32位systems.If僵尸以非常快的速度正在积累,现有的PID整池最终将成为分配给僵尸进程,防止其他进程启动。
注意:在 64 位系统上,您可以增加最大 PID,参见https://unix.stackexchange.com/a/16884/170373
然而,一些僵尸进程没有问题——尽管它们确实表明您系统上的父进程存在错误。
解释:
当一个进程在 Linux 上死亡时,它不会立即从内存中全部删除——它的进程描述符保留在内存中。
进程的状态变为EXIT_ZOMBIE
,进程的父进程被通知它的子进程已经随着SIGCHLD
信号死亡。
然后父进程应该执行 wait() 系统调用来读取死进程的退出状态和其他信息。这允许父进程从死进程中获取信息。调用wait()后,僵尸进程从内存中彻底清除。
这通常发生得非常快,因此您不会看到僵尸进程在您的系统上堆积。然而,如果父进程没有正确编程并且从不调用wait(),它的僵尸子进程将留在内存中,直到它们被清理干净。
解析度:
你不能杀死僵尸进程,因为你可以用 SIGKILL 信号杀死正常进程——僵尸进程已经死了。
杀死僵尸的一种方法是向父进程发送 SIGCHLD 信号。这个信号告诉父进程执行wait()系统调用并清理它的僵尸子进程。使用 kill 命令发送信号,将下面命令中的 pid 替换为父进程的 PID:
kill -s SIGCHLD pid
Run Code Online (Sandbox Code Playgroud)
当创建僵尸进程结束时,init 继承僵尸进程并成为它们的新父进程。(init 是启动时在 Linux 上启动的第一个进程,并被分配了 PID 1。)
注意:-从 Linux 3.4 开始,进程可以发出带有 PR_SET_CHILD_SUBREAPER 选项的 prctl() 系统调用,因此它们,而不是进程 #1,将成为其孤立后代进程的父进程。参考:https : //unix.stackexchange.com/a/177361/5132
然后 INIT 执行 wait() 系统调用来清理它的僵尸子进程,因此 init 将缩短僵尸的工作时间。您可以在关闭父进程后重新启动它。
小智 6
大多数情况下,僵尸不是一个大问题。它们是一个“死”的进程,它不需要 CPU 时间,并且任何分配的内存都应该在死亡之前被进程释放。他们实际占用的唯一资源是您的进程列表中的一个条目。根据您的系统,您可以拥有允许的最大线程数,并且僵尸可以让您无缘无故地更快地达到此限制。
但是:僵尸通常是由于代码错误/错误而出现,程序员忘记检查其子进程的状态。这可能是故意的,但通常不是。错误/错误代码通常也会以一种糟糕的 特殊方式处理内存,并且不释放一些分配的资源。如果是这种情况,这些资源将继续分配给僵尸,直到它完全终止。
编辑:如果进程是一个 java 程序,未释放的内存应该不是问题,因为 java 垃圾收集器会处理一切。
归档时间: |
|
查看次数: |
5694 次 |
最近记录: |