如果我们加载jpeg图像,为什么iOS使用较少的RAM?

时间:2015-01-29 18:31:45

标签: ios iphone opengl-es uiimage yuv

最近我们注意到我们可以将大约50个2448 x 3264(iphone相机尺寸)图像加载到屏幕上并且当前可见的UIImageViews中。 所以50个图像都被解码了。我们知道每个应用程序的iPhone内存大小约为500 MB(RAM和VRAM在一起)。如果我们将一个2448 x 3264大小的图像解码为RGB888,那么它将是24 MB,50(图像计数)* 24(一个图像大小)> 500(应用程序的内存),那怎么可能? 我们运行仪器,然后选择空白,然后从库“VM Tracker”和“IOKit”(有纹理内存)我们看到内存增加不是24 MB但是大约11.9 MB每张图片。 我们考虑可能是iOS解码jpeg文件不是RGB888而是YUV420。

有人可以帮助我们描述这种情况吗?

如果需要,我可以发送代码示例。

更新:这是一个简单的项目: https://www.dropbox.com/s/tg2r75jgzje57g8/ImageTest%202.zip?dl=0

在photoshop中有2个图像用简单的jpeg算法编码,另一个用渐进算法编码。 第一个就像我说的那样,你可以用捏合手势缩放图像,第二个用作png文件,加载32 MB内存。

2 个答案:

答案 0 :(得分:0)

如果你将一个jpeg图像加载到UIImageView中,iOS足够聪明,只能解码所需的数据,以便以屏幕上所需的大小显示,这比实际的图像大小要小得多。

对于其他图像格式(例如PNG),这是不可能的,因为它们不会像JPEG一样存储在渐进的高分辨率数据序列中 - 它们只能以原始大小进行解码(尽管你可以自己缩小它们然后丢弃原件以节省内存。)

答案 1 :(得分:0)

这里有很多事情发生,各种(和不断变化的)iOS优化会让任何获得绝对的尝试受挫;这正是X将占用多少内存。"

首先,要在UIImageView显示图像,您只需要像素所需的内存一样多。您不一定需要同时对图像中的所有像素进行完整的RGB888表示。所以你应该考虑屏幕的大小,而不是图像的大小。显然,您不会同时在iPhone屏幕上显示50x2448x3264(4亿)像素。可能存在临时峰值进行解码,但UIImageView可以创建最终结果的快照位图。 JPEG特别擅长于此,因为格式支持渐进式加载。 (请注意,iOS有一个特殊版本的PNG格式,可以为您复制到应用程序资源中的内容提供更大的压缩,因此PNG的大小可能会比您在iPhone上想象的要小。)

(顺便说一下,这就是为什么Retina iPad会有很多内存问题。无论你压缩多少图像,为了显示它,你最终都需要一个全屏的像素。)

接下来,部分UIImageView内存不一定是"收费"对你的应用程序。它们存储在可清除的内存中,操作系统可以随时丢弃。当您暂停时,这会对您的应用在内存不足情况下的行为产生非常重要的影响。暂停的应用程序没有机会响应低内存,可能会被杀死。但即使您被暂停,操作系统也会为您释放可清除的内存,因此您不太可能被杀死。

如果您正在使用imageNamed:,那么您将获得更高级别的操作系统级缓存(即不一定会对您收取费用)。在某些情况下,文件数据可以内存映射到磁盘,即使对于原始数据本身也可以避免实际内存使用。

因此,出于显示目的,通常需要进行实验以了解真实的内存要求。很难猜测iOS在优化问题方面的优势。