簡體   English   中英

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

[英]How to free and garbage collect a WebGL context?

我正在為 Web 和移動開發 WebGL 應用程序。 我經常使用硬刷新來測試我的 WebGL 實現的結果。 視圖嘗試后,我收到錯誤:

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

這不會出現在新啟動的瀏覽器上,而是在多次刷新站點后出現。 我猜 WebGL 上下文沒有正確完成、釋放、銷毀、清理、釋放。

我怎樣才能做到這一點?

Khronos Group 在此處創建了一個用於釋放和垃圾收集 WebGL 上下文的測試套件: https ://www.khronos.org/registry/webgl/sdk/tests/conformance/context/context-creation-and-destruction.html(注意:此可能會使您的瀏覽器崩潰!)

測試通過PASSTEST COMPLETE運行,所以基本上測試沒有檢測到任何問題。 然而,打開 JavaScript 控制台,它會讀取 33 個實例:

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

這是瀏覽器如何處理 WebGL 的錯誤嗎? 還是我做錯了什么? 我從沒想過釋放任何 WebGL 上下文。

我正在使用 Firefox 開發者版 48.0a2 和 Firefox 46.0.1。

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

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

你說你正在努力刷新。 意味着您在瀏覽器中按刷新? 在這種情況下,首先我會禁用所有擴展,看看問題是否仍然存在。 如果是,我會用 Mozilla 提交一個錯誤

否則,如果您嘗試釋放畫布並創建已知的畫布並希望垃圾收集良好..這是我在重新閱讀您的問題之前寫的答案


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

這里有一個釋放所有數據並重置畫布的解決方案

使用后如何從 GPU 清理和卸載 WebGL 畫布上下文?

在您的特定情況下,您是否 100% 確定您沒有保留對 WebGL 上下文或畫布的某些引用? 例如,如果你這樣做

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

你剛剛制作了一個永遠不會被垃圾收集的畫布。 它附加了一個事件偵聽器功能。 您無法刪除該函數,因為您沒有保留對它的引用。 您需要刪除所有偵聽器,這只是您可能泄漏引用的多種方式之一。

有很多方法可以不小心保留對 HTML 元素(如畫布和 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);
}

現在因為我正在跟蹤所有紋理,所以我可以輕松刪除所有剩余的紋理

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM