如何摆脱Objective-C中的常驻脏内存?

时间:2011-03-25 09:37:20

标签: objective-c xcode ios instruments

我观看了Apple的WWDC 2010关于使用Instruments进行高级内存分析的视频,从中我发现了很多常驻脏内存。我意识到拥有如此多的驻留脏内存是一件坏事(可能是我的应用崩溃了很多的解释......),但我不知道如何解决它。我应该在哪里看?

仪器向我展示了很多可能对我有用的信息,例如:

% of Res  Type                      Resident Size
18%       VM_ALLOCATE (8192 pages)  32.00 MB

这是“Dirty”类别 - 只有256 MB的设备上有32 MB的常驻脏内存,对吧? :)还有几个像这样的大块。我如何追溯到我的仪器代码?或者我应该忘记仪器并在我的代码中查找特定问题?

4 个答案:

答案 0 :(得分:29)

在设备上或模拟器中运行时,您是否看到这个32 MB的VM_ALLOCATE块?

我问,因为当我在我正在研究的OS X应用程序上使用分配工具时,我还注意到了一个32 MB的VM_ALLOCATE块,我想知道这是否是在运行中的副产品OS X环境。在设备上运行可能会为您提供不同的数据集。

通常,驻留内存是您的应用程序正在使用但未换出到磁盘的内存。在iOS上,没有交换,因此常驻内存应该等于您的虚拟内存占用量。

脏内存是您已分配和使用的内存。脏内存应该小于驻留内存,因为后者包括代码(你的和框架)。

我不确定你在你的应用中究竟做了什么,但我猜你已经从你的捆绑中加载了一些大型资产并保持它们。在可能的情况下不要这样做。

在加载使用内存映射技术的NSData对象时,也可以使用API​​,而不是使用暴力读取字节。这些可以更好,因为它允许操作系统懒惰地从磁盘读取页面。使用NSData(因为它是不可变的),它也可能足够智能将页面标记为只读。从理论上讲,这是操作系统的一个有价值的提示,它可以在压力下清除这些页面,因为它知道它们无法改变。阅读+[NSData dataWithContentsOfMappedFile:]的文档。

对于图像,我记得读过一些建议避免imageNamed:的内容,除了您经常通过应用程序使用的图像(即UI元素)。特别是对于大图像,它们可以保留在您无法控制的缓存中。 (imageNamed:在2.x天内有泄漏,但在3.x中修复了,今天使用起来非常安全。)使用imageWithContentsOfFile:查看不是经常性的较大图像和图像您的UI的一部分。

如果您要从网络加载图像,请在创建UIImage后将它们缓存在磁盘上并释放原始字节。如果由于内存压力而卸载了图像视图,则您不希望再次访问网络来加载数据,但您也不希望保留两个副本(NSData和{{1} })加载。

答案 1 :(得分:2)

使用新的xCode 4,来自xCode 3的工具仍然有更好的用户界面来分析您的应用程序,包括泄漏和内存使用情况。我建议你看看这些工具并逐个运行,看看它们为你提供了什么。您可以在主菜单Product上访问xCode 4中的那些工具,然后使用 - >资料

希望这有帮助

答案 2 :(得分:1)

在仪器中单击自动启用快照 将视图模式更改为区域映射。 在文件的路径名中查找,当你在vmpages中使用应用程序时使用它 在你清除它之后。 在视频wwdc示例中,他们使用加密文件,这是推动vmpages,没有你的代码太难建议超过[库flush]: - )

答案 3 :(得分:0)

“这是在”脏“类别 - 32 MB的常驻脏内存...” “我还注意到一个32 MB的VM_ALLOCATE,我想知道......”

当我在模拟器中分析我的应用程序时,我在VM Tracker的常驻,脏和虚拟列中看到相同的“VM_ALLOCATE(8192页)32 MB”。

为了进行比较,我分析了从Paul Hegarty的非常信息丰富的iTunes U Stanford课程(例如,心理学家和图形计算器)构建的(较小的)演示应用程序,并查看了相同的条目每个

我是一个'域名'并且还没有很好地掌握内存管理的细节,所以我不能提供权威的解释,但似乎有理由得出结论这个分配归因于元素在模拟器上运行的所有应用程序共有的框架。 (我没有在设备上运行它们。)

(仅供参考:运行10.7.3的MacBook Pro上的Xcode 4.3)