为啥我的 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 占用这么多内存?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 iOS 设备上的 glGenerateMipmap() 会占用这么多客户端内存?