为什么CIContext.createCGImage导致内存泄漏?

fla*_*nez 7 memory-leaks opengl-es core-image ios ios9

我只在iOS 9上观察到这种行为; iOS 8正常工作.

我怀疑这可能是SDK上的一个错误,我已经向Apple(22644754)开了一个雷达,但我发现它很奇怪,我觉得我可能会错过一个电话或一个避免泄漏的步骤.

我观察到的是,每次调用CIContext.createCGImage时,都会增加内存使用量.棘手的部分是内存增加发生在应用程序之外.

如果从Xcode查看"内存报告",可以在"其他进程"部分看到内存增加.

基本上,我所做的导致问题的是以下(我已经将代码简化为严格重现泄漏所需的部分):

首先,我创建一个由EAGLContext支持的CIContext:

let glContext = EAGLContext(API: .OpenGLES2)!
let ciContext = CIContext(EAGLContext: glContext, options: [kCIContextOutputColorSpace : NSNull()])
Run Code Online (Sandbox Code Playgroud)

然后,我使用以下内容渲染图像:

let input = CIImage(image: UIImage(named: "DummyImage")!)!
ciContext.createCGImage(input, fromRect: input.extent)
Run Code Online (Sandbox Code Playgroud)

DummyImage只是一个示例图像文件.泄漏与此图像的大小直接相关,因此最好使用较大的泄漏以使问题更加明显.

正如你所看到的,我没有使用任何CIFilter(使用它们导致相同的结果),而且我没有捕获生成的图像(即使我捕获它,我也无法使用CGImageRelease,因为对象是自动管理的) .

如果渲染代码执行的次数足够多,则内存将增长太多,以至于正在运行的应用程序将被杀死.

一个有趣的观察是,销毁CIContext并没有什么区别,但是破坏EAGLContext确实会返回被占用的内存.这让我觉得泄漏发生在OpenGL方面.

我在代码中遗漏了哪些可能导致泄漏的内容?我是否可以通过电话来释放EAGLContext占用的内存?(一直重新创建它不是一种选择,因为它是一项昂贵的操作).


我创建了一个简单的项目来重现这个问题.您可以在以下位置找到它:

https://www.dropbox.com/s/zm19u8rmujv6jet/EAGLContextLeakDemo.zip?dl=0

重现的步骤是:

  1. 在设备上打开并运行附加的项目.
  2. 观察Xcode上的"Memory Report"屏幕.增长将在"使用比较"饼图的"其他流程"部分中看到.
  3. 该应用程序提供三个按钮.他们每个人都会执行一定次数的createCGImage命令(显示在按钮标签上).
  4. 点击任何按钮将导致"其他进程"的内存使用量增加.执行几个createCGImage调用后,这可能会更明显.
  5. 点击100 Renders按钮将更清楚地显示效果.
  6. 当内存增长过多时,应用程序将崩溃.

fla*_*nez 1

这已被确认为 iOS 9 上的一个错误。该问题已从 iOS 9.1 beta 3 开始得到解决。

原始问题中发布的代码是正确的。iOS 9 之前的版本或 iOS 9.1 Beta 3 开始的版本无需进行任何修改来防止泄漏。