ios 设备上图像的内存管理性能不佳

Posted

技术标签:

【中文标题】ios 设备上图像的内存管理性能不佳【英文标题】:Poor memory management performance for images on ios devices 【发布时间】:2013-09-26 23:21:10 【问题描述】:

我有以下问题:

我有一个主视图对象(继承自 UIView),它以 4x4 布局显示 16 个正方形的网格(每个都是我创建的继承自 UIImageView 的类)。

这 16 个正方形中的每一个都是 160x160,并且包含不大于 30kb 的图像(每个正方形的图像不同)。然而,图像是 500x500(因为它在程序中的其他地方使用它的完整尺寸),所以它在“square”类中通过 setFrame 方法调整为 160x160。

通过查看应用程序运行时 Xcode 的内存管理功能,我注意到了一些事情:

    这些方块中的每一个在添加到主视图对象时,都会将应用程序的内存使用量增加 1MB。这不会在实例化时发生,但只有当它们被 [self addSubview:square] 添加到主视图对象时才会发生。 如果我对所有正方形使用相同的图像,内存增加是 最小。如果我初始化没有任何图像的方形对象,那么 增幅基本为零。 同一个应用,在模拟器中运行时,占用了1/6的内存 它可以在实际设备上运行。

这里的重点是:为什么在加载 30kb 的图像时每个方块会占用 1MB 的内存?有没有办法减少这种情况?我尝试了多种不同的方式来创建图像:[UIImage imageNamed:img][UIImage imageWithContentsFromFile:path][UIImage imageWithData:imgData scale:scale],以及不调整框架大小。

【问题讨论】:

【参考方案1】:

当您在较小的UIImageView 中使用 500x500 图像时,它仍在将较大的图像加载到内存中。您可以通过调整UIImage 本身的大小(不仅仅是调整UIImageViewframe)来解决此问题,制作一个160x160 的图像,然后在您的视图中使用该图像。请参阅this answer 了解一些调整图像大小的代码,然后可以按如下方式调用:

UIImage *smallImage = [image scaleImageToSizeAspectFill:CGSizeMake(160, 160)];

您甚至可能想要保存调整大小的图像,这样您就不会因为每次创建较小图像的计算开销而不断困扰自己,例如:

NSData *data = UIImagePNGRepresentation(smallImage);
[data writeToFile:path atomically:YES];

然后,您可以在以后调用视图时加载与您的小图像相对应的 PNG 文件。


回答你的问题为什么它占用这么多内存,这是因为虽然图像可能以压缩的 JPG 或 PNG 格式存储在持久存储中,但我怀疑它在内存中是作为未压缩的位图保存的。有许多内部格式,但常见的一种是 32 位格式,红色、绿色、蓝色和 alpha 各 8 位。无论细节如何,您都可以快速了解 500 x 500 像素表示,每个像素 4 个字节如何转换为 1 mb 的内存。但是 160 x 160 的图像应该是大约十分之一的大小。

【讨论】:

感谢您的快速回答和建议。我最终发现罪魁祸首是初始化 UIImageView 并告诉它调整大小,现在我在实例化 UIImageView 之前只用几行代码动态调整它们的大小,使用 UIGraphicsBeginImageContext,调整大小,从当前上下文设置新图像然后是 UIGraphicsEndImageContext。这本身就从 1MB/图像减少到 150k/图像,或多或少。不过,我会尝试一下,看看是否可以降低内存使用率。再次感谢一百万。 这正是我的建议,即首先调整图片大小。听起来你是自己想出来的。干得好!!!

以上是关于ios 设备上图像的内存管理性能不佳的主要内容,如果未能解决你的问题,请参考以下文章

MySQL性能管理及架构设计 --- 理论篇

[架构之路-47]:目标系统 - 系统软件 - Linux OS硬件设备驱动 - CPU内存管理单元MMUDMA与IO内存管理单元IOMMU

Linux内存管理

IOS内存管理详解

IOS基础之 内存管理

iOS性能优化/内存优化常用方法