WebGL deleteBuffer泄漏内存?

7
我有一个WebGL应用程序,它处理了大量的数据。在IE11上,我遇到了内存快速耗尽的问题(Chrome和Firefox没有这个问题)。然而,当我创建一些测试代码来隔离泄漏的原因时,测试代码也会在Chrome上泄漏。进一步的测试显示,即使是Chrome在实际应用程序中也会泄漏,但似乎不会像IE11那样崩溃。
以下是展示问题的测试代码的fiddle链接: EXAMPLE 基本上,我是使用以下方式创建缓冲区:
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);

我创建每个缓冲区时,也会相应地调用delete操作来删除它(在必要时):

gl.deleteBuffer(buffer);

然而,如 jsfiddle 测试代码所示,删除缓冲区似乎并没有释放浏览器使用的内存。即使缓冲区被删除,内存也会很快耗尽。
这只是一个虚构的例子,但它确实反映了我的做法(即创建缓冲区,然后再删除它们),但随着时间的推移,这样做似乎导致内存无法被释放。
我应该如何释放这个内存以避免泄漏?有任何想法吗?

1
这似乎是Chrome的一个bug。在此处提交了一个 - gman
2个回答

0

在动画循环中反复创建和删除缓冲区从来都不是一个好主意,因为它会导致视频内存碎片化。视频内存没有像Java或.NET那样强大的垃圾回收器进行管理,因为这将与性能形成强烈对比。使用“deleteBuffer”释放的内容可能直到完整的GL上下文被删除才能真正被释放以供新的使用。

如果您需要使用许多动态更改的缓冲区,请使用gl.DYNAMIC_DRAW提示,这将导致驱动程序将缓冲区存储在CPU内存中,并将其流式传输到GPU以进行每个单独的渲染(当然会有性能损失),或者保持重复使用您的缓冲区(过度提供其维度可能是明智的)。

许多专业的3D引擎仅使用一个大的顶点缓冲对象来处理所有网格,使用bufferSubData和带有偏移量的绘图命令。


我在我的动画循环中根本不创建和删除缓冲区(缓冲区是在下载数据时创建的,在离开应用程序的主页面以及其他条件等情况下被删除)。我给出的示例是为了说明删除缓冲区似乎不能释放内存,这就是我试图弄清楚的问题。 - superqd
我有同样的问题。听起来像是Chrome的一个bug,因为IE和Firefox在这个主题上工作得很好。 - David Catuhe

0

根据你对@mpfefferie的评论,你最好的选择是找到一个适合你需求的现成的对象池,或者自己制作一个。

如果不知道这个概念,可以在Pool_wiki上以非常清晰的方式解释。

如果可能的话,我会为缓冲区数组分配内存。这些保留“大”数据块的数组令人生畏。你永远无法确定它们实际上保留了多少空间。

此外,你可以重新检查是否有任何遗忘变量的引用。

如果你碰巧在预加载时有一些“闲置”的时间,你可以尝试每隔一段时间暂停渲染一段时间,这可能有助于可怜的GC完成其工作。


这是Chrome的一个bug,而且似乎在一段时间前已经得到了解决。 - superqd
@superqd 在 Mac 上使用的 Chrome 49.0.2623.112 仍然存在此问题,而在 linux 上似乎也是如此。 - user31208

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