如何摆脱Objective-C中的常驻脏内存? [英] How can I get rid of resident dirty memory in Objective-C?

查看:163
本文介绍了如何摆脱Objective-C中的常驻脏内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I watched Apple's WWDC 2010 video on Advanced Memory Analysis with Instruments and from that, I was able to find a lot of resident dirty memory. I realize that having so much resident dirty memory is a bad thing (and probably the explanation for my app crashing so much...), but I'm not sure how to fix it. Where should I look?

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

Instruments shows me a lot of potentially useful information that looks like gibberish to me, such as:

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

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

This is in the "Dirty" category - 32 MB of resident dirty memory is a lot on a device that only has 256 MB, right? :) There are several more large chunks like this. How do I trace this back to my code from Instruments? Or should I just forget Instruments and look for specific issues in my code?

推荐答案

你看到这个32 MB的VM_ALLOCATE块了吗?在设备上或在模拟器中运行?

Do you see this 32 MB chunk of VM_ALLOCATE when running on the device or in the simulator?

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

I ask because when I played around with the allocations instrument on the OS X app I'm working on, I also noticed a 32 MB chunk of VM_ALLOCATE and I'm wondering if this is a by-product of running in the OS X environment. Running on the device may give you a different data set.

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

In general, though, resident memory is the memory that your app is using that is not swapped out to disk. On iOS, there is no swap, so resident memory should equal your virtual memory footprint.

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

Dirty memory is memory you've allocated and used. Dirty memory should be less than resident memory because the latter includes code (yours and frameworks).

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

I'm not sure exactly what you're doing in your app, but I'll guess that you've loaded some large assets from your bundle and are keeping them around. Don't do this, when possible.

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

There are also APIs you can use when loading NSData objects that use a memory-mapping technique instead of brute-force reading the bytes. These can be better because it allows the OS to read the pages from disk lazily. With NSData (since it's non-mutable), it might also be smart enough to mark the pages as read-only. Theoretically, this is a valuable hint to the OS that it can purge those pages when under pressure, since it knows they can't change. Read the docs for +[NSData dataWithContentsOfMappedFile:].

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

For images, I recall reading something that suggested avoiding imageNamed: except for images that you regularly used through your app (i.e. UI elements). For large images especially, they can remain in a cache that you don't have control over. (imageNamed: had a leak in the 2.x days, but it was fixed in 3.x and is perfectly safe to use today.) Use imageWithContentsOfFile: for larger images and images that aren't a recurring part of your UI.

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

If you're loading images from the network, cache them on disk and free the raw bytes after you create the UIImage. If the image views are unloaded due to memory pressure, you don't want to hit the network to load the data again, but you also don't want to keep two copies (an NSData and the UIImage) loaded.

这篇关于如何摆脱Objective-C中的常驻脏内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆