2

我正在使用 GPUImage 对实时图像和静态图像进行大量图像处理,我注意到在翻阅了大约 100 个缩略图之后,每个缩略图都对每个图像进行了略微不同的图像处理,之后内存中仍有对象它们已完成处理,并且都与 GPUImageFilters 相关:

(分配的生命周期是“已创建且仍然存在”) 在此处输入图像描述

你可以看到我正在做的一些处理的内存峰值,完成后,在山的另一边,我在内存中留下了一些东西,我选择了一些 24KB 块来检查(还有其他块)。你可以在右边看到,第一个项目来自 GPUImageSoftLightBlendFilter,如果我点击所有 12 个项目,每个项目都来自一个 GPUImageFilter(GPUImageHardLightBlendFilter、GPUImageMultiplyBlendFilter 等)。现在,如果我再次执行相同的处理,并展开内存图选择,您将看到没有创建这些对象的新实例,就好像它们占用了内存中的空间一次,然后就闲逛了:

在此处输入图像描述

果然,如果我将内存图选择更改为仅显示第二座山,您会看到这些线不再出现,因为它们没有再次“创建并仍然存在”:

在此处输入图像描述

为什么会这样,我不希望这些 GPUImageFilter 对象的内存在我的应用程序运行的整个生命周期中一直存在?我在 GPUImageFilters 中记录了一些日志,以确认它们正在被释放并且正在调用 dealloc。

4

1 回答 1

1

从 GPUImage 源代码检查来看,最后使用的过滤器中的对象看起来GLProgram仍然由 shared 设置(并保留)GPUImageContext,这意味着其对应的 OpenGL 程序对象也不能消失。但是,现有GLProgram实现的 dealloc 仅将当前程序标记为删除。不同的是,如果当前绑定的程序是被删除的程序glDeleteTexturesglDeleteProgram它不会解除绑定,这意味着它还不能完全销毁。因此,您可能必须进行两项更改:

  1. 调用[GPUImageContext setActiveShaderProgram:nil]以清除当前的 GLProgram 绑定,这会释放对当前程序的最后引用GLProgram并将当前程序标记为删除。
  2. 通过调用 确保程序未绑定glUseProgram(0)。您可以通过多种方式执行此操作:
    • 在上面的调用之后立即显式调用它,因为正确的EAGLContext已经被绑定了。
    • 将调用添加到 的主体+[GPUImageContext setActiveShaderProgram:],或者通过在上面无条件地添加它[shaderProgram use],或者通过调用其中一个[shaderProgram use]glUseProgram(0)取决于是否shaderProgramnil
    • 检查-[GLProgram dealloc]它是否是当前绑定的程序glGetIntegerv(GL_CURRENT_PROGRAM, &program),如果是则解除绑定。
于 2013-04-27T18:57:22.790 回答