我只在iOS 9上观察到了这种行为;iOS 8可以正常工作。
我怀疑这可能是SDK上的一个bug,我已向苹果开发者提交了一个radar(编号22644754),但我觉得很奇怪,我有一种感觉可能是我错过了某个调用或步骤来避免泄漏。
我所观察到的是,每次调用CIContext.createCGImage时,都会增加内存使用量。棘手的部分是,内存增加发生在应用程序之外。
如果您查看Xcode的“内存报告”,则可以在“其他进程”部分看到内存增加。
基本上,我为了引起问题而做的是以下操作(我已经简化了代码,只保留了必要的部分以重现泄漏):
首先,我创建了一个由EAGLContext支持的CIContext:
let glContext = EAGLContext(API: .OpenGLES2)!
let ciContext = CIContext(EAGLContext: glContext, options: [kCIContextOutputColorSpace : NSNull()])
然后,我使用以下代码渲染图像:
let input = CIImage(image: UIImage(named: "DummyImage")!)!
ciContext.createCGImage(input, fromRect: input.extent)
DummyImage只是一个示例图像文件。泄漏与此图像的大小直接相关,因此最好使用大图像以使问题更加显着。
如您所见,我没有使用任何CIFilters(使用它们会导致相同的结果),也没有捕获生成的图像(即使我捕获了它,我也不能使用CGImageRelease,因为这些对象是自动管理的)。
如果渲染代码执行足够多次,则内存将增长得如此之多,以至于正在运行的应用程序将被杀死。
有趣的观察是销毁CIContext并不会有任何区别,但是销毁EAGLContext确实会返回占用的内存。这使我认为泄漏发生在OpenGL侧。
我的代码中是否缺少任何可能导致泄漏的内容?我能做出哪些调用以释放EAGLContext所占用的内存?(每次重新创建它都不是一种选择,因为这是一项代价高昂的操作)。
我创建了一个简单的项目来重现此问题。 您可以在以下位置找到它: https://www.dropbox.com/s/zm19u8rmujv6jet/EAGLContextLeakDemo.zip?dl=0 重现步骤如下:
- 在设备上打开并运行附加的项目。
- 观察Xcode上的“内存报告”屏幕。增长将在“使用情况比较”饼图的“其他进程”部分中看到。
- 应用程序显示三个按钮。每个按钮将执行createCGImage命令特定次数(显示在按钮标签上)。
- 点击任何一个按钮都会导致“其他进程”的内存使用增加。这可能在执行多个createCGImage调用后更为明显。
- 点击100次渲染按钮将更清楚地显示效果。
- 当内存增长过多时,应用程序将崩溃。
bytesPerPixel = 8
?kCIFormatRGBA8
不是每像素4字节的格式吗? - Jean-Denis Muys