2016-05-06 56 views
6

我正在開發WebGL和移動WebGL應用程序。我經常使用硬刷新來測試WebGL實現的結果。視圖嘗試後,我得到的錯誤:如何釋放和垃圾收集WebGL上下文?

Error: WebGL: Exceeded 16 live WebGL contexts for this principal, losing the least recently used one. 

這似乎不是一個新鮮的開始瀏覽器,但多次刷新網站後,。我猜WebGL上下文沒有完成,發佈,銷燬,清理,正確釋放。

我該怎麼做?

Khronos工作組創建了一個測試套件,用於釋放和垃圾在這裏收集的WebGL方面:https://www.khronos.org/registry/webgl/sdk/tests/conformance/context/context-creation-and-destruction.html(注:這可能會崩潰您的瀏覽器!)

測試貫穿與PASSTEST COMPLETE,所以basicly測試未檢測任何問題。但是,打開JavaScript控制檯,它讀取33個實例:

Error: WebGL: Exceeded 16 live WebGL contexts for this principal, losing the least recently used one. 

這是WebGL如何由瀏覽器處理的錯誤?或者我做錯了什麼?我從來沒有想過要釋放任何WebGL上下文。

我使用Firefox Developer Edition 48.0a2和Firefox 46.0.1。

如何釋放和垃圾收集WebGL上下文?

回答

2

我想,也許我誤解你的問題

你說你在做硬刷新。這意味着你在瀏覽器中刷新了?在這種情況下,首先我會禁用所有擴展並查看問題是否仍然存在。如果是我會提交一個bug與Mozilla

否則,如果你想免費的畫布,創造知道的人,並希望垃圾收集以及..這裏是我寫了我以前的答案重讀你的問題


簡短的回答是你不能強制垃圾收集。你最好重新使用相同的畫布。

這裏有一個解決方案,以釋放所有數據並重置畫布

How do I clean up and unload a WebGL canvas context from GPU after use?

你的具體情況雖然你100%確定你不是抱着一些參考WebGL的上下文或帆布?例如,如果你這樣做

canvas.addEventListener('click', function(..) {}); 

你剛做了一個永遠不會被垃圾收集的畫布。它附有一個事件監聽器功能。你沒有辦法刪除該功能,因爲你沒有保留對它的引用。您需要刪除所有聽衆,只是您可能泄露引用的許多方式的一個示例。

There's tons of ways to accidentally keep references to HTML elements like the canvas as well as WebGL objects。保持超過零引用,並且永遠不會被垃圾收集。

Here's some hints on finding the leaks

在另一方面,如果是我,我會嘗試重新使用的畫布。爲了確保我釋放了一切,我可能會調用我自己的創建/刪除功能來跟蹤所有資源。例如

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); 
} 

現在,因爲我跟蹤所有的紋理,我可以很容易地刪除所有剩餘的

while (textures.length) { 
    gl.deleteTexture(textures.pop()); 
}