什么是僵尸以及它们产生的原因是什么?是否存在僵尸进程和僵尸对象?
我可以找到有关僵尸的问题,但没有一个直接解决它们是什么以及它们发生的原因和方式。有一些在回答特定问题的背景下解决了什么是僵尸进程,但没有解决原因。
还有关于僵尸进程的问题和关于 Objective-C/Cocoa 相关僵尸对象的问题。有什么区别或者它们之间有什么关系? Mac/iPhone 上的“EXEC_BAD_ACCESS”(或其他平台上的类似错误)是否与僵尸同义?
如何预防僵尸?是否有任何最佳实践可以帮助避免它们?
将这些信息放在一处将会很有帮助。如果可能的话,这个问题的目的是与平台/语言无关。
I can find questions about zombies but none that directly addresses what they are and why and how they occur. There are a couple that address what zombie processes are in the context of answering a specific question but don't address the cause.
There are also questions regarding zombie processes and questions about Objective-C/Cocoa-related zombie objects. What are the differences or how are these related? Is an "EXEC_BAD_ACCESS" on Mac/iPhone (or similar error on other platforms) synonymous with a zombie?
How can one prevent zombies and are there any best practices that will help avoid them?
It would be helpful to have this information in one place. This question is intended to be platform/language agnostic, if possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
僵尸进程和僵尸对象完全无关。僵尸进程是指父进程启动子进程并且子进程结束,但父进程没有获取子进程的退出代码。进程对象必须一直存在,直到发生这种情况 - 它不消耗任何资源并且已经死亡,但它仍然存在 - 因此,“僵尸”。
僵尸对象是 Cocoa / CoreFoundation 的一项调试功能,可帮助您捕获内存错误 - 通常当对象的引用计数降至零时,它会立即释放,但这使调试变得困难。相反,如果启用了僵尸对象,则该对象的内存不会立即释放,它只是被标记为僵尸,并且任何进一步使用它的尝试都会被记录下来,您可以追踪该对象在其生命周期之后在代码中的使用位置。
EXEC_BAD_ACCESS 是您的常规“您使用了错误的指针”异常,就像我这样做一样:
Zombie processes and zombie objects are totally unrelated. Zombie processes are when a parent starts a child process and the child process ends, but the parent doesn't pick up the child's exit code. The process object has to stay around until this happens - it consumes no resources and is dead, but it still exists - hence, 'zombie'.
Zombie objects are a debugging feature of Cocoa / CoreFoundation to help you catch memory errors - normally when an object's refcount drops to zero it's freed immediately, but that makes debugging difficult. Instead, if zombie objects are enabled, the object's memory isn't instantly freed, it's just marked as a zombie, and any further attempts to use it will be logged and you can track down where in the code the object was used past its lifetime.
EXEC_BAD_ACCESS is your run-of-the-mill "You used a bad pointer" exception, like if I did:
当一个进程结束时,它的大部分状态仍然存在于内核中,因为它的父进程可能仍然想要查看一些东西,比如它的返回值,它需要存储在某个地方。当父进程调用 wait() 或 waitpid() 时,它告诉内核将其全部丢弃,因为它已经完成了。在此之前,子进程会保留 pid 并耗尽资源。那些未回收的子进程称为僵尸进程。即使杀死僵尸也不能消除它,它必须被它的父母收割(等待)。如果父进程死亡,它们将被传递给 unix 系统上的“init”,其唯一的工作是等待事物来清理它们。
我从来没有听说过“僵尸对象”,但我认为它指的是那些要么没有被垃圾收集器清理的东西,要么有循环引用或类似的东西,这样它们就不会被清理由垃圾收集器收集。这个比喻非常相似:在一定程度上 fork()==malloc()、wait()==free()。 (当然,这不是一个完美的比喻。)
When a process ends, much of its state still exists in the kernel, because its parent may still want to look at a few things, like its return value, which needs to be stored someplace. When a parent calls wait() or waitpid(), it tells the kernel to throw it all away because it's done with it. Until it does so, the child retains a pid and uses up resources. Those un-reaped child processes are called zombies. Even killing a zombie won't remove it, it must be reaped (wait-ed-upon) by its parent. If the parent dies, they are passed to "init" on unix systems, whose sole job is to wait for things to clean them up.
I've never heard of "zombie objects", but I assume that it refers to things that have either not been cleaned up by the garbage collector, or that have circular references or some such thing, such that they are not going to be cleaned up by the garbage collector. The metaphor is pretty similar: fork()==malloc(), wait()==free() at a certain level. (Not a perfect metaphor, of course.)