setNeedsDisplay,drawRect或CALayer导致dispatch_continuation_alloc_from_heap malloc内存泄漏iOS
我在应用程序中遇到内存泄漏,似乎来自CALayer。 看起来好像只影响老iPad; 我看到iPad 1和2的问题,但iPad Air没问题。 我有一个iPad 1的崩溃报告,显示我的应用程序由于内存不足而“被抛弃”,这个漏洞是我的主要嫌疑。
背景
在操作期间,setNeedsDisplay每40ms由不同的UIViews上的networking线程不断地调用,以更新它们的视觉效果,参见下面的函数。
- (void)setNeedsRepaint { [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; }
模拟iPad2并使用分配工具,我发现每次setNeedsDisplay被调用时,malloc 64的引用计数都会永久上升。 负责的库是libdispatch.dylib,调用者是dispatch_continuation_alloc_from_heap。
iPad Air模拟器不显示此问题,在这种情况下,malloc 32引用计数只是暂时上升。
即使在setNeedsDisplay来自GUI线程并且不通过performSelectorOnMainThread调度的情况下,我也看到malloc 64引用计数上升。
以下是分配工具的屏幕截图。 标记为3的malloc是有问题的泄漏。 标记为1&2的malloc泄漏得慢得多,但仍然是一个小问题。
采取的步骤
为了排除drawRect中的内存泄漏,我注释了大括号之间的所有代码,但泄漏的内存仍然继续积累。
如果我不重写drawRect方法,我不会看到泄漏,但我需要为了绘制和更新我的视图。 我也没有看到它,如果setNeedsDisplay不被调用,我可以调用一个虚拟函数,而不是内存泄漏performSelectorOnMainThread。
我已经尝试使用块和dispatch_async而不是performSelectorOnMainThread在GUI线程上运行setNeedsDisplay。
我也尝试减less应用程序,以便setNeedsDisplay只能在一个视图上重复调用。 然后删除所有指向该视图的指针,以便ARC清理它,希望stream浪的malloc可能会被清理干净。
我试着直接设置CALayer的内容而不是调用setNeedsDisplay。 它呈现,但malloc计数完全相同的方式上升。
self.layer.contents = (__bridge id) _dummyCGImageRef;
读完这个之后,我认为泄漏可能是由于队列变得臃肿。 然而,我的函数调用速度减慢了10倍,只是使内存泄漏增长了10倍。
结论
泄漏似乎绑定到CALayer,而不是调度队列和performSelectorOnMainThread。 看起来这个问题在以后的iPad中已经修复,但是我仍然需要一个解决旧版本的解决方法。
问题
有没有人有任何提示debugging呢?
另一种仪器是否更适合find确切的原因?
这是模拟器的一个特点,我看到的不是我的应用程序抛弃的原因吗?
任何人都知道这是什么原因? 这是一个历史性的bug,因为它不影响iPad Air?
我有一个子类化的技巧,我可以用CALayer来防止后备存储分配内存,或另一种方式我更新我的视觉视觉?
谢谢。