iOS 内存被打爆及内存暴增的问题

一、内存被打爆

问题

UIImageView使用SDWebImageProgressiveLoad模式加载一张5MB以上的图片。

   [[SDImageCache sharedImageCache] clearDiskOnCompletion:nil];//这行为了方便测试
   NSURL *url = [NSURL URLWithString:@"http://106.52.146.151:8081/examples/photos/IMG_11MB.jpg"];
   [_contentImageView sd_setImageWithURL:url placeholderImage:nil options:SDWebImageProgressiveLoad completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

   }];
iOS 内存被打爆及内存暴增的问题_第1张图片
内存暴增

说明:上述链接是我自己玩的服务器,过个几个月可能过期了,读者找一张大点图片放在自己的服务器。
测试是在模拟器测试的,iPhone8大概500MB左右就会被强杀。

原因

iOS 内存被打爆及内存暴增的问题_第2张图片
instruments分析

didReceiveData在不断接收数据,[self.imageData copy],imageData是NSMutableData。在解码1.1MB时,1.2MB,1.3MB数据回来了,再解压1.2MB数据时,更多的数据回来了,造成内存挤压。
实际情况,1.1MB解压时,如果后面有更多的数据回来,只需要解压最大的那个即可。不需要1.2MB,1.3MB这样解压。

解决方案

  1. 针对大数据慎用copy
  2. 去掉串行队列、下次数据来时直接丢失上次数据;
  3. 压缩图片,不要太大的图片;
  4. 去掉copy不会内存暴增,但再大一点数据如8MB以上,大概需要内存500MB左右

二、for 循环引起内存暴增

问题:进入页面发现内存一直在暴增

iOS 内存被打爆及内存暴增的问题_第3张图片
内存一直在增长

原因

iOS 内存被打爆及内存暴增的问题_第4张图片
instrument查找原因

定位到具体方法,发现了这行的问题:


错误代码

上述等价于下面的这段:


iOS 内存被打爆及内存暴增的问题_第5张图片
最大值.png

由于self.defaultsArray是nil,而count是NSUInteger,所以count做了位运算,是64位机器下最大值。而刚好这个循环在做view添加操作,导致添加了无限个view。导致内存一直在增大。

小结

  1. count-1由于count是无符号值,所以算出的值应该是越界了。就像int在32位机器超出65535一样,结果不可预料。
  2. 循环还是使用enumerateObjectsUsingBlock方法,这个方法是多线程的,效率高。

你可能感兴趣的:(iOS 内存被打爆及内存暴增的问题)