【发布时间】:2020-09-08 11:28:03
【问题描述】:
我正在看一本关于父子进程的教科书,作者说:
如果父进程在没有收割僵尸子进程的情况下终止,则内核会安排 init 进程收割它们。但是,shell 或服务器等长期运行的程序应该总是收割它们的僵尸孩子。即使僵尸没有运行,它们仍然会消耗系统内存资源。
但是根据这个问题的答案What does reaping children imply?
似乎大多数/所有僵尸的资源都被释放了,只有一个肯定仍在消耗的资源是进程表槽。我不熟悉进程表槽,但我认为它存储了僵尸的退出状态。
不管怎样,进程表槽中的一条记录听起来没什么大不了,可能只是在内存中消耗了几个字节/kb,所以为什么长时间运行的程序应该总是通过调用@987654322 来收割它们的僵尸孩子@变体?
【问题讨论】:
-
问题不在于一两个僵尸进程,而是数量不断增加。例如,如果长时间运行的进程是一个可以调用任何其他程序的 shell。这些调用的程序可能不会收获它的孩子,所以外壳会继承它们。如果现在 shell 调用了许多这样的程序(它可能是因为用户控制了 shell 所做的事情),如果 shell 不定期收割它继承的孩子,僵尸的数量可能会变得非常大。
-
长期运行可能意味着数年。让我们随机猜测一个僵尸使用 200 个字节。如果你设法在一年内每分钟泄漏一个,你已经在无用的僵尸上烧掉了 100 兆字节的不可交换的内核内存。而像 ps 和 top 这样的东西现在必须在 Z 状态下经过半百万个进程。
-
当然,在 32 位 linux 上,PID 限制是 32768,僵尸不会释放它们的 PID,一旦你的 PID 用完,系统就会被冲洗掉。
-
@Ackdari Orphans 总是由 init 继承,而不是由他们的祖父母继承。
-
我认为与资源的适度泄漏相比,刺激是一个更大的问题。试图找到一个特定的运行进程,当你有数百个同名的僵尸时,会很快变老。
标签: c linux fork child-process zombie-process