Afr*_*Afr 9 javascript free garbage-collection webgl destroy
我正在为Web和移动开发WebGL应用程序.我经常使用硬刷新来测试我的WebGL实现的结果.视图尝试后,我收到错误:
Error: WebGL: Exceeded 16 live WebGL contexts for this principal, losing the least recently used one.
Run Code Online (Sandbox Code Playgroud)
这不会出现在新启动的浏览器上,而是在多次刷新网站后出现.我想WebGL上下文没有完成,发布,销毁,清理,正确释放.
我怎样才能做到这一点?
Khronos Group在这里创建了一个用于释放和垃圾收集WebGL上下文的测试套件:https://www.khronos.org/registry/webgl/sdk/tests/conformance/context/context-creation-and-destruction.html(注意:这个可能会崩溃您的浏览器!)
测试通过PASS和TEST COMPLETE,所以基本上测试没有检测到任何问题.但是,打开JavaScript控制台,它会读取33个实例:
Error: WebGL: Exceeded 16 live WebGL contexts for this principal, losing the least recently used one.
Run Code Online (Sandbox Code Playgroud)
这是浏览器如何处理WebGL的错误吗?或者我做错了什么?我从没想过要释放任何WebGL上下文.
我正在使用Firefox Developer Edition 48.0a2和Firefox 46.0.1.
如何释放和垃圾收集WebGL上下文?
我想也许我误解了你的问题
您说您正在努力刷新。表示您要在浏览器中按“刷新”?在那种情况下,我首先禁用所有扩展,然后查看问题是否仍然存在。如果是,我会向mozilla提交错误
否则,如果您尝试释放画布并创建已知的画布并希望很好地进行垃圾收集..这是我在重新阅读您的问题之前写的答案
简短的答案是您不能强制垃圾回收。您最好重新使用相同的画布。
这里有一个解决方案,可以释放所有数据并重置画布
使用后如何从GPU清理WebGL canvas上下文并从其中卸载?
但是,在您的特定情况下,您是否100%确定不保留对WebGL上下文或画布的某些引用?例如,如果您这样做
canvas.addEventListener('click', function(..) {});
Run Code Online (Sandbox Code Playgroud)
您刚刚制作了一个永远无法进行垃圾收集的画布。它具有附加的事件侦听器功能。您没有办法删除该功能,因为您没有对其进行引用。您需要删除所有侦听器,这只是泄漏引用的多种方式中的一个示例。
有无数种方式意外保留对HTML元素(如canvas以及WebGL对象)的引用。保留超过零个引用,并且永远不会对其进行垃圾回收。
另一方面,如果是我,我会尝试重新使用画布。为了确保释放所有内容,我可以调用自己的创建/删除函数来跟踪所有资源。例
var textures = [];
function createTexture(gl) {
var tex = gl.createTexture();
textures.push(txt);
}
function deleteTexture(gl, tex) {
gl.deleteTexture(tex);
textures.splice(textures.indexOf(tex), 1);
}
Run Code Online (Sandbox Code Playgroud)
现在,由于我正在跟踪所有纹理,因此可以轻松删除所有剩余的纹理
while (textures.length) {
gl.deleteTexture(textures.pop());
}
Run Code Online (Sandbox Code Playgroud)