Jet*_*awi 6 memory-management cgimage ios
当我创建UIFmage实例时,我似乎有一个内存管理问题,CGImages没有被释放.
我有一个分页UIScrollView来滚动浏览一系列JPG图像.下面是我的整个类,它是分页滚动视图中的页面视图.
代码正在主线程上运行.该代码使用ARC.我尝试使用imageWithContentsOfFile加载图像:(返回一个自动释放的对象)以及initWithContentsOfFile :(返回一个保留的对象).我已经尝试了@autoreleasepool并使用performSelectorOnMainThread来确保代码在主线程上运行,如其他帖子中所建议的那样.
在滚动图像时,内存使用量会一直增长,直到应用程序终止,如图所示.注意图像io的高分配.
屏幕截图显示虚拟内存使

在下面的屏幕截图中,可以看到GTGImageScrollerPageViews,UIImageViews和UIImages正在被释放.请注意,高300中的这些编号有Transitory对象.然而,CGImages没有被发布,CGImages生活的数量在高400和0 Transitory.
显示分配的屏幕截图

编辑:以前我一直在回收和重新使用ScrollView中的GTGImageScrollerPageView实例,这是像这样的滚动视图的常见模式.为了简化尝试调试此问题的时间,我允许在ScrollView中显示整个GTGImageScrollerPageView后取消分配.正如您在上面的第二张图片中看到的那样,只有4个GTGImageScrollerPageView生活和377瞬态,还有388个UIImageViews和389个UIIMages列为暂时的,因此看起来UIImageViews和UIImages正在被释放.
如果我用CGImageRelease手动释放CGImage(在下面的代码中注释掉),CGImages将被释放.我知道我不应该这样做,因为我不拥有CGImage,但这有助于验证这是问题发生的地方.下面的屏幕截图显示了在仪器中测试的相同代码,但CGImageRelease未注释.
屏幕截图显示了使用CGImageRelease的虚拟内存使用情况

屏幕截图显示了使用CGImageRelease的分配

在使用CGImageRelease的分析输出中,您可以看到正确数量的CGImage对象是Living和Transitory,并且内存不会无限增长.此外,在使用CGImageRelease时,应用程序不会崩溃.
如果这是CGImage的一些系统缓存,那么它应该在引发内存警告时释放内存,但事实并非如此.记忆力继续增长.
这可能导致内存无限增长?
这是页面视图的代码
编辑:作为对评论的回应,我更新了代码以进一步简化,从而消除了诸如ivars和不需要证明问题所需的属性的干扰.问题保持不变,分析时结果相同.我还在NSLog中添加了也输出线程.我确实看到在GTGImageScrollerPageView上按预期调用了dealloc,它始终是线程#1,并且对displayAspectThumbImage的调用始终在线程#1上.
我真的不相信这里提供的代码有任何问题,Rob的慷慨努力证实了这一点.还有其他因素造成这种情况,但是加载和显示图像的所有代码都在这里; 这里没有其他有效的代码.我能想到的另一个值得注意的事情是,从滚动视图委托的scrollViewDidScroll和scrollViewDidEndDecellerating方法调用displayAspectThumbImage方法,但是在主线程上调用方法的事实应该排除由于在另一个线程上运行而导致的自动释放问题.
我已经检查过并且NSZombies没有启用,并且没有僵尸增加我的内存使用量.实际上,当调用CGImageRelease方法时,内存使用非常平坦,如上面的屏幕截图所示.
@implementation GTGImageScrollerPageView
- (void)dealloc {
NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSThread currentThread]);
}
- (void)displayAspectThumbImage:(NSString *)path {
NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSThread currentThread]);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.bounds];
[self addSubview:imageView];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
[imageView setImage:image];
//If uncommented CGImages are disposed correctly
//CGImageRelease([imageView.image CGImage]);
}
@end
Run Code Online (Sandbox Code Playgroud)
测试:
iOS 6.1.4
iOS 5.0.1
真的很抱歉自己回答这个问题,但我认为分享我的经验会很有用。
事实证明,它是 UIImage 上的一个类别,是我正在使用的第三方库的一部分。我不会命名该库,因为我已经使用最新版本进行了测试,并且问题不存在,因此命名该库没有任何好处。
这是特别奇怪的,因为该库没有在泄漏代码附近的任何地方使用。它只在整个项目中的一个地方使用,但每当我使用 UIImage 时,它似乎都会影响 UIImage 实例。该类别在项目中的存在就足够了。这真是一个惊喜。
我解决这个问题的方法是首先在一个新项目中模拟场景,发现代码没有泄漏。然后,我一次迁移了一点代码,当我移动类别时,泄漏出现了。
非常感谢 Rob 慷慨地帮助我解决这个问题,尽管他没有直接提供解决方案,但与他交谈对解决问题确实很有帮助。很高兴知道外面有这么酷的人。
| 归档时间: |
|
| 查看次数: |
1800 次 |
| 最近记录: |