36

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

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

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

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

4

2 回答 2

38

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

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

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

(*(0x42)) = 5;
于 2010-07-10T20:16:36.460 回答
9

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

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

于 2010-07-10T20:16:06.897 回答