WebGL deleteBuffer泄漏内存?

时间:2014-04-16 21:54:13

标签: javascript memory-leaks webgl

我有一个管理大量数据的WebGL应用程序。我在IE11上遇到了问题,因为它快速耗尽内存(Chrome和FF没有出现此问题)。但是,当我创建一些测试代码来隔离泄漏的原因时,测试代码也会在Chrome上泄漏。进一步的测试显示,即使Chrome在实际应用程序中泄漏,或者看起来似乎没有像IE11那样崩溃。

以下是展示问题的测试代码的小提琴: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);

对于我创建的每个缓冲区,我也会进行相应的调用以将其删除(必要时删除):

gl.deleteBuffer(buffer);

但是,正如在jsfiddle测试代码中可以看到的,删除缓冲区似乎不会释放浏览器使用的内存。即使缓冲区被删除,它也会很快耗尽内存。

这显然是一个人为的例子,但它确实反映了我正在做的事情(即创建缓冲区并稍后删除它们),但随着时间的推移,这似乎会导致内存无法被释放。

我应该如何释放这些内存以避免泄漏?有什么想法吗?

2 个答案:

答案 0 :(得分:0)

在动画循环中重复创建和删除缓冲区永远不是一个好主意,因为它会导致视频内存碎片化。视频内存不受Java或.NET等功能强大的垃圾收集器的管理,因为它与性能形成鲜明对比。什么" deleteBuffer"在删除完整的GL上下文之前,实际上可能不会释放新用途。

如果需要使用大量动态更改缓冲区,请使用gl.DYNAMIC_DRAW提示,这将导致驱动程序将缓冲区存储在CPU内存中,并将其流式传输到GPU以进行每次渲染(性能损失为当然)或继续重复使用你的缓冲区(建议过度配置它的维度)。

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

答案 1 :(得分:0)

根据你对@mpfefferie的评论,听起来你最好的选择就是找到一个可以随时使用的(根据你的需要)objects pool,或者自己做一个。

这个概念,如果不知道,将在Pool_wiki上以非常明确的方式解释。

如果可能的话,我会为 buffers 数组分配内存。保留“大”数据块的这类数组是可怕的。你永远无法确定他们为自己保留了多少空间。

此外,您可以重新检查是否遗漏了对变量的任何遗忘参考。

如果您有任何机会在预加载时获得一些“备用”时间,您可以尝试每隔一段时间暂停渲染一段时间,这可能有助于穷人{{1}做它的工作。