objective-c - 废弃内存和内存泄漏有什么区别?

标签 objective-c ios memory-management memory-leaks abandoned-memory

两者完全相同,只是“废弃内存”是指泄漏的整个对象图,而不仅仅是单个对象。正确的?

最佳答案

首先,您需要了解“内存对象图”或“应用程序对象图”(或者简单地说,“对象图”,因为它适用于分配的缓冲区)的概念。在这种情况下,“对象”指的是应用程序中的任何分配,无论是对象还是简单的 malloc() ed 缓冲区。如果任何对象都可以包含对其他对象的引用(指针),则为“图形”部分。

应用程序的“事件对象图”是可以从应用程序中的各种“根”直接或间接访问的所有分配。 “根”本身就是对对象的实时引用,而不管其他任何东西是否显式地引用了根。

例如,全局变量是根;通过引用一个对象,一个全局变量,根据定义,使该对象成为应用程序事件对象图的一部分。并且,通过暗示,全局变量引用的对象也被认为是事件的;没有泄露。

堆栈也是如此;任何线程的事件堆栈引用的任何对象本身都被认为是事件的。

考虑到这一点,泄漏被遗弃的内存实际上确实有两个不同的含义。

泄漏

泄漏是一 block 内存,没有来自应用程序事件对象图中任何事件对象的分配引用。

IE。内存无法访问,因此无法再次引用它(除非出现错误)。这是死内存。

请注意,如果对象 A 指向对象 B,对象 B 指向 A,但事件对象图中没有任何内容指向 A 或 B,则它仍然是泄漏。如果 B->A 和 A->B 引用都是保留引用,那么您将获得保留循环和泄漏。

被遗弃的内存

在应用程序的事件对象图中但由于应用程序逻辑问题而不再可访问的分配被视为已放弃,但未泄漏。

例如,假设您有一个缓存,其条目是 NSData 的实例。从某个 URL 下载的 URL 在 URL 中包含 session ID(一种常见模式),并且该 session ID + URL 用作在缓存中查找内容的键。现在,假设用户注销,导致 session ID 被破坏。如果缓存没有删除所有特定于该 session ID 的条目,那么所有这些 NSData对象将被丢弃,但不会泄露,因为它们仍然可以通过缓存访问。

实际上,在两者之间做出如此强烈的区分几乎没有用处,因为修复需要非常不同的策略。

修复泄漏是要找出额外保留的来源(或者在基于 free() 的泄漏的情况下,可能需要插入对 malloc() 的丢失调用)。由于无法从事件对象图中找到检测到的泄漏,因此修复泄漏真的很简单。

由于几个原因,修复废弃的内存可能相当棘手。

首先,内存仍然可以从事件对象图中访问。因此,根据定义,您的应用程序中存在保持内存事件的算法问题。发现和修复它通常比修复一个泄漏要困难得多,并且可能具有破坏性。

其次,可能存在对废弃分配的非归零非保留弱引用。也就是说,如果你弄清楚在哪里修剪强引用并让分配真正消失,那并不意味着你的工作已经完成;如果还有任何剩余的非归零弱引用,它们现在将是悬空指针和..... 繁荣 .

正如阿米特所说,Heapshot Analysis非常善于发现泄漏、废弃的内存以及——非常重要的——整体“不希望的内存增长”。

关于objective-c - 废弃内存和内存泄漏有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8840168/

相关文章:

c++ - 链表内存读取错误

android如何下载一个1mb的图像文件并设置为ImageView

c++ - C++ 模板的替代方案

ios - 创建 ViewController 的最佳方式

ios - Swift - 有一个音频重复,但它在间隔播放?

ios - 如何将p12文件转换为base64字符串?

java - 创建 "could not reserve enough space for object heap"错误

objective-c - 核心数据迁移的验证错误

ios - 如何在iOS中进行三角形,圆形匹配等图像模式匹配?

ios - Cocos2d 和 iOS : is there a way to stop the screensaver from starting in my game?