ios - 由于内存压力,应用程序不断崩溃

标签 ios objective-c cocoa-touch memory xcode-instruments

我的应用程序正在保存和检索来自 Parse.com 的数据。并显示图像、按钮、 ScrollView 等(正常的东西)。然后,当我接近完成我的应用程序时,它开始收到内存警告,并且应用程序开始经常崩溃。我在仪器中检查了它,发现某些点的实时字节非常高,但我不明白为什么。

应用程序是否因高事件字节而崩溃?事件字节的值应该是多少?

显然虚拟机中发生了一些事情。但我不知道这是什么。什么是VM:CG 栅格数据?还有这个:VM:CG 图像?我不使用 CGImages 仅使用 UIImages

最佳答案

Is the app crashing because of the high live bytes?

是的。

What should value of the live bytes be?

没有固定的数字。限制因操作系统版本而异,有时取决于设备以及当前发生的其他情况。正确的做法是 (a) 尽量不要使用太多,以及 (b) 注意警告并处理掉不需要的东西。

Obiously something is going on in the VM. But I have no idea what this is. What is the VM: CG raster data? And this: VM: CG Image? I am not using CGImages only UIImages

一个UIImage只是 CGImage 的包装。

同时存在的图像太多。这就是你必须解决的问题。

那么,多少算太多呢?这取决于它们有多大。

另请注意,“栅格数据”是解压后的大小。 5Mpix RGBA 8bpp 图像需要 20MB 的 RAM 来存储其光栅数据,无论文件是 8MB 还是 8KB。


I still feel the number is too high though, or is 30-40 MB an okey number handling 3-6 full-screen sized images at a time? This is when tested on a 4 year old iPhone4, iOS 7. If that matters.

在 iPhone 4 上,“全屏”意味着 640x960 像素。 8bpp RGBA 表示每个像素 4 个字节。因此,有 6 个这样的图像,即 640*960*4*6 = 14MB。因此,如果您已加载并绘制 6 个全屏图像,这就是您应该期望的绝对最小存储空间。

那么,为什么您实际上看到的数字是两倍以上?

嗯,如Images and Memory Management在类引用中说:

In low-memory situations, image data may be purged from a UIImage object to free up memory on the system. This purging behavior affects only the image data stored internally by the UIImage object and not the object itself. When you attempt to draw an image whose data has been purged, the image object automatically reloads the data from its original file. This extra load step, however, may incur a small performance penalty.

因此,可以将这 14MB 视为 iOS 用来加快速度的缓存,以防您想再次绘制图像。如果你的运行内存有点低,它会自动清除缓存,所以你不必担心。

因此,您还剩下 16-24MB,这可能是由 UI 小部件和图层的缓冲区以及幕后的合成器使用的。这比理论最小值 14MB 稍多一点,但也不是太严重。

如果你想进一步减少内存使用,你可能需要做的不是绘制所有 6 个图像。如果它们是全屏的,用户就无法一次看到超过 1 或 2 个。因此,您可以按需加载和渲染它们,而不是预加载它们(或者,如果您可以预测接下来通常需要哪一个,则预加载其中 1 个而不是全部),并在它们不再可见时销毁它们。由于此时您只有 2 个图像而不是 6 个图像,因此内存使用量应该会从 16-24MB + 14MB 缓存降低到 5-9MB + 5MB 缓存。这显然意味着需要更多的 CPU — 它可能不会明显影响响应能力或电池消耗,但您需要对此进行测试。而且,更重要的是,它肯定会让你的代码变得更加复杂。

显然,如果适合您的图像,您还可以使用非 Retina 图像(这将减少 75% 的内存)或将颜色深度从 RGBA-8 降低到 ARGB-1555 (50%),但是大多数图像看起来并不那么好(这就是我们拥有高色彩视网膜显示屏的原因)。

关于ios - 由于内存压力,应用程序不断崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25516543/

相关文章:

ios - 一个数组排序后,如何改变两个数组的顺序?

ios - 如何正确使用 setNeedsDisplay()

ios - PFQueryTableView 无法填充 TableView

ios - 在不使用自动布局或制作新的 xib 的情况下从 iPhone 5 调整 iPhone 4 的大小

objective-c - 在 OSX 中将 subview 拖到 super View 之外

iphone - 如何修复错误 'No memory available to program now: unsafe to call malloc'?

iphone - 如何添加具有相同属性的多个 UIImageView

ios - 我如何在 iOS 中获取捕获的图像路径?

objective-c - 在 TextView 后面添加背景图片

javascript - 帮助在 UIWebView 中使用 Javascript 代码