内存泄漏和僵尸有啥区别?

Posted

技术标签:

【中文标题】内存泄漏和僵尸有啥区别?【英文标题】:What is the difference Memory Leak and a Zombie?内存泄漏和僵尸有什么区别? 【发布时间】:2012-09-21 23:15:51 【问题描述】:

我正在做一个基于 ARC 的项目。我从未从事过基于非 ARC 的项目。最近我

在我启用 ARC 的项目中遇到了一个僵尸。据我所知,不会有记忆

ARC 中的泄漏,因为对象将被自动释放。但我遇到了一个僵尸

说“消息传递给一个已释放的实例”。我的困惑是内存泄漏等价物

对僵尸。如果是这种情况,那么 ARC 中也会发生内存泄漏吗?有什么帮助吗?

【问题讨论】:

一具没有灵魂的尸体,据说是用巫术复活的。 这不是 ARC 的错。假设你有一些弱指针并且它被释放了,那么你就会看到。 @iBlue:当对象被解除分配时,ARC 下的适当弱指针将变为 nil,但“传递给解除分配实例的消息”的基本点是由持有指向具有的对象的指针引起的被释放是正确的。 @Isaac 是的,我是说如果在它被释放后你尝试对它做点什么,那么你会看到,这不是 ARC 的错。 这可能会帮助你:***.com/questions/8275805/…, ***.com/questions/10804865/… 【参考方案1】:

Objective-C 用语中的“僵尸”与泄漏相反。泄漏是您不再有任何引用的已分配内存,因此您无法释放它。僵尸是一个已经被释放的对象,但是对它的引用仍然存在并且消息仍然被发送给它(这可能导致各种不可预知的行为)。

【讨论】:

他“解决”了混乱:p @guru 它们关系密切——僵尸是一种识别对象悬空指针的方法。 这在 Swift 中还能发生吗?我的意思是,如果您向已释放的对象发送消息,那么您将得到的只是(强制)解开 nil 对象的 fatalError 对吗?我假设在安全访问的情况下你不会有问题......但是如果我错了并且它可能发生在 Swift 中,那么你可以分享一个示例代码来重新创建一个僵尸对象,因为虽然我已经创建了内存周期,我认为我从来没有能够创建一个僵尸对象 有关我之前评论的答案,请参阅:How can I demonstrate a zombie leak for Swift?【参考方案2】:

有多种可能性,如果不看代码就很难知道发生了什么。 “传递给已释放实例的消息”错误意味着您有一个指向对象所在位置的指针,但此后已被释放。这可以并且仍然会发生在 ARC 中。这可能是因为你有一些非 ARC 代码(或者可能是 Core Foundation 的东西)与 ARC 代码交互,并且在交接时事情会出错。也可能发生这种情况,因为虽然 ARC 几乎每次都会选择正确的时间点来释放对象,但这并不完美(通常有办法解决这些情况)。

【讨论】:

以上是关于内存泄漏和僵尸有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

内存泄漏和内存溢出有啥区别?

markdown 重构#4:RxJS内存泄漏,僵尸订阅和错误

请解释一下“内存泄漏”,这个问题会有啥影响

QtWebKit 内存泄漏有啥解决办法吗?

用 Rust 处理 WebAssembly 中的闭包而不是使用忘记和泄漏内存有啥更好的方法?

Android:浅堆和保留堆有啥区别