什么是CG栅格数据?

我试图在代码中发现另一个内存泄漏,我似乎无法弄清楚CG栅格数据是什么。 在启用自动快照的情况下浏览VM跟踪器时,CG栅格数据似乎是唯一增加的部分。 没有拨款的增加,这些也在稳步增加。

我不完全确定CG栅格数据是什么,也不知道如何修复它,但在这一点上越来越多的脚印最终导致内存错误和崩溃,所以它不好! 我做我自己的文字渲染(使用CoreText),所以我想这与它有关。 我也在加载图片?

以下是足迹的图像: 当页面加载时,应用程序分配的峰值(应用程序以离散方式加载图像和文本的页面),脏内存总是增加。

更新:这个问题仍然存在,但有趣的是,我可以将它与Uifoundations中的一个泄漏相关联,称为“NSConcreteGlyphGenerator”。 它似乎只发生在实际绘制的CoreText方法中的属性string上的“boundingRectWithSize:”方法。 具体而言,该行是:

[displayString boundingRectWithSize:CGSizeMake( self.frame.size.width, self.frame.size.height ) options:0 context:nil]; 

慢慢地跟踪它…

我不知道“CG栅格数据”可能包含的所有内容,但是我确切知道它包含的一件事是…由Core Graphics分配的用于存储栅格数据(又名位图)的内存。

具体来说,在我的应用程序中,我使用CGBitmapContextCreate创build了两个256×256位图上下文。 我传递NULL作为data参数,以便Core Graphics为我分配位图内存。 每像素32位(4字节)的256×256位图需要256 KiB = 64页,每个4 KiB。 在乐器中,我得到两个“CG栅格数据”块,每块65页。 如果我注释掉其中一个位图上下文,那么在Instruments中我只能得到一个65页的“CG光栅数据”块。

另一方面,我的应用程序中也有一个CATiledLayerCATiledLayer为我绘制了自己的graphics上下文,我相信它会使用共享内存创build这些上下文,即窗口服务器(iOS 5上的springboard ,iOS 6上的backboard )也可以直接访问这些上下文。 我没有看到与这些graphics上下文对应的任何“CG栅格数据”块。

通过简单地重复推入和popup视图控制器,我也遇到了与CG栅格数据存储器相同的问题。 我花了一段时间认为这是一个绘图代码的问题。 我终于跟踪到一个委托不弱引用视图控制器被推动和popup,所以当我popup视图控制器,它不被释放。 CG栅格数据恰好是这个视图控制器足迹中最大的一部分,所以我错误地把这个问题归结为这个问题:当它真的是视图控制器本身没有被释放的时候(因此,没有发布它的观点,有CG栅格数据)。

简而言之:如果您发现CG Raster Data存在内存泄漏,请查看可能有视图的视图控制器,并确保它们正在被释放。

这不是一个很好的答案,但有人开始调查…

我认为CG栅格数据是iOS 6的新增function,但作为CG Image在iOS 5中出现。 我在两个模拟器上进行了testing,在iOS 5上,CG栅格数据不存在,但是如果您比较iOS 6和iOS 5上的总量,则CG图像几乎等于CG栅格数据,CG图像不在iOS 6上显示。所以我很确定他们只是将CG Image重命名为CG栅格数据。

至于CG Image究竟是什么,好吧,我一直在试图弄清楚几个月。 我认为这只是视图布局相关的事情由系统处理,你不真正控制,因为我的应用程序没有任何UIImages或CG图像,我的CG图像内存是相当高,所以它可能要做的事情与核心animation和视图布局。

当我遇到这个问题时,“CG栅格数据”来自我从UIGraphicsBeginImageContextWithOptions中调用UIGraphicsGetImageFromCurrentImageContext创build的图像。 我花了一天的时间来追踪这个问题,最终与形象完全没有关系。 在我的情况下,我无意中将图像粘贴到另一部分代码中的自己的NSCache中,而没有意识到这一点。

如果您在CG栅格数据未发布时遇到问题,则应考虑数据创build位置的来源可能与实际问题无关。 这可能是因为您不希望图像数据被保留下来,而您在“乐器”中看到的“CG栅格数据”标签只是指数据的来源。 你应该检查一下,以确保你没有像多个addSubviews一样的东西,而无法removeFromSuperview(例如与UIImageViews),或将图像放入caching,数组,强variables等。

如果你担心内存使用(89MB)是一点点。 你有没有试过模拟模拟器中的内存警告(模拟器>硬件>模拟内存警告)?

我的猜测是它的内存被图片图片用完。

您可能需要通过观察内存警告消息来释放您的映像:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 

清除handleMemoryWarning方法中的所有图像对象。

不是一个真正的答案。 但是在解决我的CG-raster-data-leak问题时,我想到了一些更多的提示:

  • cg-raster-data保存CGIMageRefs的内存(至less是从CGBitmapContextCreate(NULL,…)创build的上下文中的CGBitmapContextCreateImage()创build的)
  • 我的泄漏是一个缺less的CGImageRelease()。 我使用该图像作为CALayer的内容传递,并假定此属性拥有引用。 但似乎这个任务复制图像。 至less我在调用CGImageRelease后没有任何问题。

希望能帮助别人…