为啥我的 UIImage 占用这么多内存?

Posted

技术标签:

【中文标题】为啥我的 UIImage 占用这么多内存?【英文标题】:Why does my UIImage take up so much memory?为什么我的 UIImage 占用这么多内存? 【发布时间】:2014-03-26 13:11:09 【问题描述】:

我有一个 UIImage 正在加载到我的应用程序的一个视图中。这是一个 10.7 MB 的图像,但是当它在应用程序中加载时,应用程序的资源使用量突然增加了 50 MB。为什么这样做?使用的内存不应该只增加大约 10.7MB 吗?我确信加载图像是导致内存使用量跳跃的原因,因为我尝试将这些行注释掉,内存使用量又回到了 8 MB 左右。这是我加载图像的方式:

UIImage *image = [UIImage imageNamed:@"background.jpg"];
self.backgroundImageView = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:self.backgroundImageView];

如果没有办法减少这个图像使用的内存,有没有办法在我想要的时候强制它释放?我正在使用 ARC。

【问题讨论】:

您可以调整图像大小,然后将其设置为背景。 【参考方案1】:

不,不应该是 10.7MB。 10.7MB 是图像的压缩大小。 加载到UIImage 对象中的图像是解码后的图像。

对于图像中的每个像素,使用 4 个字节(R、G、B 和 Alpha),因此您可以计算内存大小,高 x 宽 x 4 = 内存中的总字节数。

因此,当您将图像加载到内存中时,它将占用大量内存,并且由于 UIImageView 用于呈现图像,并且作为子视图,图像被保存在内存中。

您应该尝试更改图像的大小以匹配 ios 屏幕的大小。

【讨论】:

更深入的计算解释给有兴趣的人:shutha.org/node/789 它被加载到内存中的时刻是什么时候? UIImage *image = [UIImage imageNamed:@"background.jpg"];或 self.backgroundImageView = [[UIImageView alloc] initWithImage:image]; 当你创建 'UIImage' 对象时。【参考方案2】:

正如@rckoenes 所说 不要显示具有高文件大小的图像。 您需要在显示之前调整图像大小。

UIImage *image = [UIImage imageNamed:@"background.jpg"];
self.backgroundImageView =[self imageWithImage:display scaledToSize:CGSizeMake(20, 20)];//Give your CGSize of the UIImageView.
[self.view addSubview:self.backgroundImageView];


-(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize 
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

【讨论】:

当您可以提供较小尺寸的图像时,为什么还要在设备上浪费 CPU 资源。 @rckoenes 是的,你是对的。但如果他想从其他来源获取图像,上述解决方案会有所帮助【参考方案3】:

你可以做一件事。如果你能负担得起这张图片的 50 MB。如果这个大小为 10 mb 的图像对您的应用程序非常重要,那么。您可以在使用后立即释放它以控制内存使用。 由于您使用的是 ARC,因此没有发布选项,但您可以这样做

@autoreleasepool 
UIImage *image = [UIImage imageNamed:@"background.jpg"];
self.backgroundImageView = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:self.backgroundImageView];        

使用 autoreleasepool 可以确保在此 autoreleasepool 块内存用于胖图像之后将被释放。让您的设备 RAM 再次快乐起来。

希望对你有帮助!

【讨论】:

这根本不会减少内存,因为您分配给视图的UIImageView 仍然持有对图像的引用。所以它仍然会保存在内存中。

以上是关于为啥我的 UIImage 占用这么多内存?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 QML Image 占用这么多内存?减慢申请

为啥 Java 中的 HashSet 占用这么多内存?

为啥 iOS 设备上的 glGenerateMipmap() 会占用这么多客户端内存?

Pytorch:为啥`tensor`变量占用的内存这么小?

为啥我的安卓手机内存卡,里面有的只有几百b的文件,却占用了300多kb的大小?

HTML:为啥元素占用这么多宽度?