【问题标题】:What are Zombies and what causes them? Are there Zombie processes and Zombie objects?什么是僵尸,是什么原因造成的?有僵尸进程和僵尸对象吗?
【发布时间】:2011-03-14 08:04:15
【问题描述】:

我可以找到有关僵尸的问题,但没有一个可以直接解决它们是什么以及它们为什么以及如何发生的问题。有几个在回答特定问题的情况下解决了僵尸进程是什么,但没有解决原因。

还有关于僵尸进程的问题和关于 Objective-C/Cocoa 相关的僵尸对象的问题。有什么区别或它们之间有什么关系? Mac/iPhone 上的“EXEC_BAD_ACCESS”(或其他平台上的类似错误)是僵尸的同义词吗?

如何预防僵尸?是否有任何最佳实践可以帮助避免它们?

将这些信息放在一个地方会很有帮助。如果可能,此问题旨在与平台/语言无关。

【问题讨论】:

    标签: zombie-process


    【解决方案1】:

    当一个进程结束时,它的大部分状态仍然存在于内核中,因为它的父进程可能仍然想查看一些东西,比如它的返回值,这些东西需要存储在某个地方。当父进程调用 wait() 或 waitpid() 时,它会告诉内核把它全部扔掉,因为它已经完成了。在它这样做之前,孩子会保留一个 pid 并用完资源。那些未收获的子进程称为僵尸。即使杀死僵尸也不会将其移除,它必须由其父母收割(等待)。如果父级死了,它们会被传递给 unix 系统上的“init”,它唯一的工作就是等待清理它们。

    我从未听说过“僵尸对象”,但我认为它指的是那些没有被垃圾收集器清理的东西,或者有循环引用或类似的东西,这样它们就不会去由垃圾收集器清理。比喻非常相似:fork()==malloc(), wait()==free() 在某个级别。 (当然,这不是一个完美的比喻。)

    【讨论】:

    • 僵尸进程消耗的唯一资源是它在内核进程表中的条目。在那一点上,其他所有东西都被回收了,因为它死了,吉姆。 (而且init 也有其他职责,但您通常只会在出错时看到这些职责。)
    • @donal:我认为信号代码也在其中。并且在等待期间/之后仍然可以编写核心吗?另外,通过“用完资源”,我主要指的是 pid 本身,因为您可能会用完这些资源,尤其是在每个用户的基础上。 :-)
    • 嗯,我还认为“僵尸对象”是循环引用阻止垃圾收集器收集某些对象的结果。你会说这个帖子对此做出了否定的回应吗?
    【解决方案2】:

    僵尸进程和僵尸对象完全不相关。僵尸进程是指父进程启动子进程,子进程结束,但父进程没有获取子进程的退出代码。进程对象必须一直存在,直到发生这种情况 - 它不消耗任何资源并且已经死亡,但它仍然存在 - 因此,'僵尸'。

    Zombie objects 是 Cocoa / CoreFoundation 的调试功能,可帮助您捕获内存错误 - 通常当对象的引用计数降至零时,它会立即释放,但这会使调试变得困难。相反,如果启用了僵尸对象,则对象的内存不会立即释放,它只是被标记为僵尸,并且任何进一步使用它的尝试都将被记录下来,您可以追踪该对象在其生命周期后的代码中的使用位置.

    EXEC_BAD_ACCESS 是您的普通“您使用了错误的指针”异常,就像我一样:

    (*(0x42)) = 5;
    

    【讨论】:

    • 好的,我知道僵尸进程是什么,但为什么会发生这种情况?这是父进程的编程错误,系统故障,超自然力量吗?那么,所谓的僵尸对象就是用来捕捉悬空指针,即引用一个内存已被释放的对象的指针?
    • 是的,是父母做错了什么。你已经掌握了僵尸对象
    • 从概念上讲,我认为它们是相关的:两者都被“杀死”,但在某种意义上仍然“活着”。
    • 至于“EXEC_BAD_ACCESS”类型的错误,好像不一定非得是丧尸。如果你做了一些可怕的指针算术,你可能会得到那种类型的错误,但你仍然在某个地方有一个有效的对象(你只需要让你的指针正确引用它)。另外,我明白你的例子的重点,但理论上它可以工作,如果星星正确对齐(不太可能,只是说'),对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 2013-04-11
    • 2013-05-01
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    相关资源
    最近更新 更多