什么样的内存泄漏 XCode Analyzer 可能不会注意到?

Posted

技术标签:

【中文标题】什么样的内存泄漏 XCode Analyzer 可能不会注意到?【英文标题】:What kind of memory leaks XCode Analyzer may not notice? 【发布时间】:2013-02-23 23:19:39 【问题描述】:

我担心问这个问题可能会导致一些反对意见,但在做了一些不满意的研究后,我决定冒险并问更有经验的人......

这里有很多问题是指与 XCode Analayzer Tool 相关的一些具体问题。这似乎是一个非常有用的解决方案。但是我想问你——作为ios世界的初学者——这个工具不能注意到什么样的内存管理东西。

换句话说,有没有什么常见的内存管理方面,iOS 初学者应该考虑一下“哦,要小心,因为在这种情况下,XCode Analyzer 可能不会警告你你的错误 “...

例如,我在这里找到了Why cannot XCode static analyzer detect un-released retained properties?:

(...)分析器无法可靠地检测保留/释放问题 方法/库边界(...)

这听起来像是一个值得考虑的好提示,但也许您知道其他一些常见问题......

【问题讨论】:

仅仅因为一个工具可以检测到泄漏并不意味着你不应该少考虑内存管理。它是一种工具,而不是仔细思考的替代品。 【参考方案1】:

分析器非常擅长发现困扰编写非 ARC 代码的新程序员的例程泄漏(未能调用 release、返回错误保留计数的对象等)。

根据我的经验,它没有发现几种类型的内存问题:

它通常无法识别strong reference cycles(又名retain cycles)。例如,您将重复的NSTimer 添加到视图控制器,不知道计时器保持对视图控制器的强引用,如果您不invalidate 计时器(或在错误的地方执行,例如dealloc 方法),视图控制器和计时器都不会被释放。

找不到循环逻辑错误。例如,如果您有一些循环引用,其中视图控制器 A 呈现视图控制器 B,而视图控制器 B 又呈现 A 的新副本(而不是关闭/弹出以返回 A)。

找不到很多非引用计数内存问题。虽然它在处理 Core Foundation 函数方面变得越来越好,但如果您的代码正在执行手动内存分配(例如通过 mallocfree),静态分析器的使用可能会受到限制。当您使用非引用计数代码时也是如此(例如,您使用 SQLite sqlite3_prepare_v2 并且未能调用 sqlite3_finalize)。

我确信这不是它找不到的完整列表,但这些是我在 Stack Overflow 上看到的常见问题,静态分析器对此的帮助有限。但分析器仍然是一个很棒的工具(它还能发现内存问题以外的问题),对于那些不使用 ARC 的人来说,它是无价的。

话虽如此,虽然静态分析器是被低估的第一道防线,但您确实应该使用 Instruments 来查找漏洞。请参阅Instruments 用户指南中的Locating Memory Issues in Your App。这是识别泄漏的最佳方法。

【讨论】:

您能否进一步说明为什么 invalidate 你的定时器在 dealloc 中会不好? @MarkBernstein dealloc 仅在没有对视图控制器的强引用时才被调用。因此,因为重复计时器保持对视图控制器的强引用,所以它永远不会被调用。将invalidate 放在dealloc 中类似于说“当没有更多对此视图控制器的强引用时,继续删除计时器对该视图控制器的强引用”。您通常将invalidate 放在viewWillDisappear 或类似的地方,具体取决于您的应用程序的详细信息。

以上是关于什么样的内存泄漏 XCode Analyzer 可能不会注意到?的主要内容,如果未能解决你的问题,请参考以下文章

使用Memory-Analyzer分析内存泄漏

Java内存泄漏分析工具Memory Analyzer Tool

手把手:Java内存泄漏分析Memory Analyzer Tool

Memory Analyzer Tool定位Java heap space内存泄漏

使用Eclipse Memory Analyzer进行内存泄漏分析三部曲

使用Eclipse Memory Analyzer进行内存泄漏分析三部曲