ope*_*rog 12 memory-leaks memory-management objective-c ios abandoned-memory
两者完全相同,只是"废弃的内存"指的是泄漏的整个对象图而不是单个对象.对?
bbu*_*bum 27
首先,您需要理解"内存对象图"或"应用程序对象图"(或简称为"对象图",因为它适用于已分配的缓冲区)的概念.在这种情况下,"对象"指的是应用程序中的任何分配,无论是对象还是简单的malloc()ed缓冲区."图形"部分,如果是任何对象可以包含对其他对象的引用 - 指针.
应用程序的"活动对象图"是可以直接或间接从应用程序中的各种"根"到达的所有分配."根"本身就代表对象的实时引用,而不管其他任何内容是否明确引用了根.
例如,全局变量是根; 通过引用一个对象,根据定义,全局变量使该对象成为应用程序的实时对象图的一部分.并且,通过暗示,全局变量引用的对象的任何对象也被认为是活动的; 没有泄露.
堆栈也是如此; 任何线程的实时堆栈引用的任何对象本身都被认为是实时的.
考虑到这一点,泄漏和遗弃的记忆实际上确实有两个不同的含义.
泄漏是一段内存,对应用程序的活动对象图中的任何活动对象都没有引用.
即内存无法访问,因此无法再次引用它(禁止错误).这是死记忆.
请注意,如果对象A指向对象B而对象B指向A,但实时对象图中没有任何内容指向A或B,则它仍然是泄漏.如果B-> A和A-> B引用都是保留引用,那么您将获得保留周期和泄漏.
应用程序的实时对象图中由于应用程序逻辑问题而无法再访问的分配被视为放弃,但不会泄露.
例如,假设您有一个缓存,其条目是NSData从某个URL下载的实例,其中URL包含URL中的会话ID(常见模式),并且该会话ID + URL用作查找内容的密钥缓存.现在,假设用户注销,导致会话ID被销毁.如果缓存未被修剪特定于该会话ID的所有条目,则所有这些NSData对象将被放弃,但不会泄漏,因为它们仍然可以通过缓存到达.
实际上,没有什么用于区分两者之间的区别,因为修复需要非常不同的策略.
修复泄漏是为了找出额外保留的来源(或者在基于泄漏free()的情况下可能需要插入缺少的调用malloc()).由于无法从实时对象图中获得检测到的泄漏,因此修复泄漏确实非常简单.
由于几个原因,修复废弃的内存可能会相当棘手.
首先,仍然可以从实时对象图中访问内存.因此,根据定义,您的应用程序中存在一个保持内存存活的算法问题.寻找和修复通常会更加困难并且可能具有破坏性,因此只需要修复泄漏.
其次,对于废弃的分配可能存在非归零的非保留弱引用.也就是说,如果你弄清楚在哪里修剪强引用并使分配实际消失,那并不意味着你的工作已经完成; 如果有任何剩余的非归零弱引用,它们现在将是悬空指针和..... BOOM.
正如阿米特指出的那样,快照分析非常善于发现泄漏,遗弃的记忆和非常重要的整体"不良记忆增长".
不确定是否有标准术语,但也有可能存在内存,其中确实有参考,但永远不会被使用。(Leaks 工具的 Heap Shot 功能可以帮助追踪这一点。)我将其称为“膨胀”,以将其与真正的泄漏区分开来。两者都是浪费内存。
| 归档时间: |
|
| 查看次数: |
1828 次 |
| 最近记录: |