【发布时间】:2013-08-15 15:31:45
【问题描述】:
我在 Instruments 中使用 VM Tracker 运行我的应用,发现 Image IO 内存消耗不断增加。
实际上,该应用使用initWithContentsOfFile: 从磁盘读取了很多图像。我曾经读到这个方法是撒旦的产物,所以我用下面的方法替换它:
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:data];
这大大减少了虚拟内存(约60%),如下图:
但是,为什么 Image IO 虚拟内存会随着时间的推移而不断增长,而没有任何泄漏并且我的应用程序只使用 15MB 的实时内存?
我可以做些什么来确保这个 Image 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 dataWithContentsOfFile:path options:NSDataReadingUncached error:nil] - 将
UIImage *image = [UIImage imageWithData:data];移至主队列 - 在主队列上做所有事情
这让我觉得问题可能出在其他地方。
【问题讨论】:
-
在分配工具中,您可以将调用堆栈的所有记录转换为分配事件。也许你在某处有一个额外的意外保留?
-
@nielsbot 如果有,那么实时内存会不会更高(更接近虚拟内存)?也就是说,我已经检查了 Instruments 和静态分析仪中的泄漏。
-
我想我主要是对分配的来源感到好奇。
-
@nielsbot 给你 :) imgur.com/UowiGKR
-
好的——看起来有很多 CFData 对象...如果单击 CFData 旁边的显示详细信息箭头然后浏览实例,查看每个分配事件的记录调用堆栈以查看分配的原因。
标签: ios uiimage instruments