应用程序是否因为高活动字节而崩溃?
是的。
活动字节的值应该是多少?
没有固定的数字。限制因操作系统版本而异,有时取决于设备以及目前正在发生的其他情况。正确的做法是 (a) 尽量不要使用太多,并且 (b) 注意警告并丢弃不需要的东西。
虚拟机中显然发生了一些事情。但我不知道这是什么。什么是 VM:CG 栅格数据?还有这个:VM:CG Image?我不只使用 CGImages UIImages
UIImage 只是 CGImage 的包装。
您同时拥有太多图像。这就是你必须解决的问题。
那么,多少才算太多?这取决于它们有多大。
另外,请注意“光栅数据”是解压缩的大小。一张 5Mpix RGBA 8bpp 的图像需要 20MB 的 RAM 来存储其光栅数据,无论文件是 8MB 还是 8KB。
我仍然觉得这个数字太高了,还是 30-40 MB 是一个可以同时处理 3-6 个全屏大小图像的数字?这是在使用 4 年的 iPhone4、iOS 7 上测试的。如果这很重要的话。
在 iPhone 4 上,“全屏”是指 640x960 像素。 8bpp RGBA 表示每个像素 4 个字节。因此,对于 6 个这样的图像,即 640*960*4*6 = 14MB。因此,如果您已经加载并绘制了 6 张全屏图像,那么这就是您应该期望的绝对最小存储空间。
那么,为什么你实际看到的不止两倍呢?
好吧,正如课程参考中的Images and Memory Management 所说:
在内存不足的情况下,可能会从 UIImage 对象中清除图像数据以释放系统内存。这种清除行为只影响 UIImage 对象内部存储的图像数据,而不影响对象本身。当您尝试绘制其数据已被清除的图像时,图像对象会自动从其原始文件重新加载数据。然而,这个额外的加载步骤可能会导致小的性能损失。
因此,将 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%),但是大多数图像看起来并不那么好(这就是我们使用高色彩 Retina 显示器的原因)。