什么是CG光栅数据?

26

我正在尝试查找代码中的另一个内存泄漏问题,但我似乎无法弄清楚CG Raster Data是什么。当我启用自动快照的VM Tracker时,CG Raster Data似乎是唯一增加的部分。这些还在稳定增长,而不会使分配增加。

我不确定CG Raster Data到底是什么,也不知道该如何修复它,但现在内存占用不断增加最终会导致内存错误和崩溃,这不好!我使用CoreText进行自己的文本呈现,所以我认为这可能与此有关。我还加载图片吗?

以下是内存占用的图像: Peaks in the allocations when the pages load (the app loads pages with images and text discretely), the dirty memory always increases though.

更新:这个问题仍然存在,但有趣的是我可以将其与UIFoundations中的一个叫做“NSConcreteGlyphGenerator”的泄漏相关联。只有在我在CoreText方法中调用带有属性字符串的“boundingRectWithSize:”方法时才会发生。具体地,该行是:

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

正在慢慢追踪它...


4
你解决过这个问题吗?我在iOS 7上仍然遇到了这个问题。 - Daniel
这个有更新了吗?@Daniel - Ríomhaire
6个回答

12

我不知道“CG栅格数据”可能包含什么,但有一件事我可以确定,它包含了由Core Graphics分配的用于存储光栅数据即位图的内存。

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

另一方面,我的应用程序中还有一个CATiledLayerCATiledLayer为我设置了自己的图形上下文,我相信它使用了共享内存,窗口服务器(iOS 5上的springboardiOS 6上的backboard)也直接访问该内存。我没有看到与这些图形上下文对应的“CG栅格数据”块。


3
我曾经遇到过CG光栅数据内存不断增加的问题,只是简单地重复推出和弹出一个视图控制器。我花了一段时间认为这是一些绘图代码的问题。最后我发现是委托没有弱引用正在推出和弹出的视图控制器,所以当我弹出视图控制器时,它没有被释放。CG光栅数据恰好是那个视图控制器占用内存最大的部分,因此我最初错误地将问题归因于它,而实际上是视图控制器本身没有被释放(因此无法释放其视图,其中有一些包含CG光栅数据)。
简而言之,如果您在使用CG光栅数据时发现内存泄漏,请查看可能具有视图的视图控制器,并确保它们被释放。

1
如果您担心内存使用量(89MB)有点高,请尝试在模拟器中模拟内存警告(Simulator > Hardware > Simulate Memory Warning)。
我猜测这是图片所占用的内存。
很有可能您需要通过观察内存警告消息来释放您的图片。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];

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


如何清除所有图像?是指image = nil还是self.view = nil - aircraft

1
当我遇到这个问题时,“CG Raster Data”是从我通过UIGraphicsBeginImageContextWithOptions调用UIGraphicsGetImageFromCurrentImageContext创建的图像中获取的。我花了一天时间来追踪问题,最终发现它与如何创建图像根本没有关系。在我的情况下,我无意中将图像放入了另一个代码部分中的NSCache中,而没有意识到这一点。
如果您遇到CG Raster Data未被释放的问题,您应该考虑数据创建的来源很可能与实际问题无关。可能只是简单地保留了图像数据,而您并不希望它被保留,而您在Instruments中看到的“CG Raster Data”标签只是指示数据的来源。您应该检查是否做了类似于多次添加子视图而没有调用removeFromSuperview(例如使用UIImageView)或将图像放入缓存、数组、强变量等的操作。

我似乎遇到了非常相似的问题。您能详细说明将图像放入NSCache中的问题吗? - Kenneth

1

这并不是一个很好的答案,但至少可以让某人开始调查了...

我认为CG Raster Data是iOS 6中的新功能,但在iOS 5中作为CG Image存在。我在两个模拟器上进行了测试,在iOS 5上,CG Raster Data不存在,但如果你比较iOS 6和iOS 5的总量,CG Image几乎等于CG Raster Data,并且在iOS 6上不显示CG Image。所以我相信他们只是将CG Image重命名为CG Raster Data。

至于CG Image到底是什么,我已经试图弄清楚了几个月。我认为它只是由系统处理的与视图布局相关的东西,你无法真正控制,因为我的应用程序没有任何UIImages或CG Images,而我的CG Image内存非常高,所以它可能与核心动画和视图布局有关。


“CG Image” 在 iOS 6 中仍然存在,至少在我的应用程序中。 - rob mayoff
是的,对我来说也是如此,尽管它只有极小的痕迹。在 iOS 5 中它大约为 20 MB,在 iOS 6 中最多只有 32 KB。所以无论 CG Image 是什么,它在 iOS 6 中都不扮演那么重要的角色。 - Snowman

0

不是真正的答案。但是在解决我的CG光栅数据泄漏问题时,我发现了一些更多的提示:

  • cg-raster-data保存了CGIMageRefs的内存(至少是从由CGBitmapContextCreate(NULL,...)创建的上下文中使用CGBitmapContextCreateImage()创建的)
  • 我的泄漏是缺少CGImageRelease()。我使用图像作为CALayer的内容传递,并假设此属性保存引用。但似乎此赋值会复制图像。至少在分配后立即调用CGImageRelease没有问题。

希望能对某人有所帮助...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接