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

Jos*_*own 23 xcode objective-c instruments ios

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

乐器向我展示了许多对我来说看起来像胡言乱语的潜在有用信息,例如:

% of Res  Type                      Resident Size
18%       VM_ALLOCATE (8192 pages)  32.00 MB
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*sen 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和多个UIImage).