我观看了 Apple 的 WWDC 2010 视频《Advanced Memory Analysis with Instruments》,从中我发现了大量常驻脏内存。我意识到拥有如此多的常驻脏内存是一件坏事(这可能是我的应用程序崩溃的原因......),但我不知道如何修复它。我应该去哪里看?
Instruments 向我展示了许多潜在有用的信息,但对我来说看起来像是胡言乱语,例如:
% of Res Type Resident Size
18% VM_ALLOCATE (8192 pages) 32.00 MB
这是“脏”类别 - 32 MB 常驻脏内存对于只有 256 MB 的设备来说已经很多了,对吧? :) 还有几个像这样的大块。我如何从 Instruments 追溯到我的代码?或者我应该忘记仪器并寻找代码中的特定问题?
在设备或模拟器中运行时,您是否看到这个 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:
对于较大的图像和不是用户界面中重复出现的部分的图像。
如果您从网络加载图像,请将它们缓存在磁盘上,并在创建后释放原始字节UIImage
。如果图像视图由于内存压力而被卸载,您不想再次访问网络来加载数据,但您也不想保留两个副本(一个NSData
和UIImage
)已加载。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)