Ios 图像IO内存不断增长
我在装有虚拟机跟踪器的Instruments中运行我的应用程序,发现图像IO内存消耗不断增加 实际上,该应用程序使用Ios 图像IO内存不断增长,ios,uiimage,instruments,Ios,Uiimage,Instruments,我在装有虚拟机跟踪器的Instruments中运行我的应用程序,发现图像IO内存消耗不断增加 实际上,该应用程序使用initWithContentsOfFile:从磁盘读取了大量图像。我曾经读过一篇文章,说这个方法是撒旦的产物,所以我用下面的方法代替了它: NSData *data = [NSData dataWithContentsOfFile:path]; UIImage *image = [UIImage imageWithData:data]; 这大大减少了虚拟内存(约60%),如下
initWithContentsOfFile:
从磁盘读取了大量图像。我曾经读过一篇文章,说这个方法是撒旦的产物,所以我用下面的方法代替了它:
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:data];
这大大减少了虚拟内存(约60%),如下所示:
但是,为什么图像IO虚拟内存会随着时间的推移不断增长,而我的应用程序只使用了15MB的实时内存
我可以做些什么来确保释放此图像IO内存吗?
基本上,从磁盘读取图像的过程如下:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
});
我还尝试了以下方法,但没有任何重大变化:
- 使用
[NSData DATA WITH CONTENTS OFFILE:path options:NSDATAREADINGUCACHED error:nil]
- Move
UIImage*image=[UIImage-imageWithData:data]代码>到主队列
- 在主队列上执行所有操作
这让我觉得问题可能在别处。您至少应该将后台处理打包到自动释放池中:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {
@autoreleasepool {
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
}
});
通过这种方式,您可以确保背景线程上的所有自动释放对象尽快消失。多亏了我发现图像被NSCache
保留
问题是NSCache
没有释放任何内存对象警告。解决方案:让它观察UIApplicationIDReceiveMemoryWarningNotification
,并在发生这种情况时删除其所有对象。这就是仪器现在的样子:
乐器太棒了。感谢@NikolaiRuhe和@nielsbot让我挖得更深
另外,我应该补充一点,使用
NSData
时内存消耗会降低,因为dataWithContentsOfFile
不考虑视网膜文件(d'uh)。所以imageWithContentsOfFile:
可能仍然是撒旦的后代,但这并不是撒旦的错 在Allocations instrument中,您可以打开分配事件调用堆栈的所有记录。也许你有一个额外的意外保留sonewhere?@nielsbot如果有,活动内存会比虚拟内存高很多吗?这就是说,我已经检查了仪器和静态分析仪中是否存在泄漏。我想我主要对分配的来源感到好奇。@nielsbot给你:)好吧——看起来有很多CFData对象。。。如果单击CFData旁边的“显示详细信息”箭头,然后浏览实例,查看每个分配事件记录的调用堆栈,以查看分配的原因。这难道不是不必要的吗?知道数据可以在imageWithData:
之后释放,并且图像可以在第二次调度\u async
结束时释放,这难道还不够聪明吗?@hpique否。如果启用了优化,并且调用方和调用方都进行了优化,ARC有时可能会避免将对象放入自动释放池被调用方是使用ARC编译的,但您不能依赖它。此处dataWithContentsOfFile:
创建一个自动删除的对象,如果添加池,该对象会消失得更快。您也可以尝试将NSDataReadingMappedaways
传递到dataWithContentsOfURL:options:错误: