如何查看特定JS对象的可达性

问题描述 投票:0回答:1

我有一个WebAssembly实例,它创建一个WebGL2上下文。理想情况下,退出显示上下文的页面部分时,我想破坏上下文并让模块和纹理等被垃圾回收。问题是,我无法找到保留对WebAssembly对象的引用的内容。

如何参考该对象标识所有位置(属性,闭包)? (Chrome devtools或其他易于使用的工具)

javascript webgl webassembly
1个回答
0
投票

我不确定这是否是您的问题的答案,但是...在您写的详细信息中

我想破坏上下文并让模块和纹理等被垃圾回收。

让纹理等被垃圾收集是清理WebGL资源的错误方法。参见Are WebGL objects garbage collected?

如果知道何时完成WebAssembly,则可以通过扩展上下文来跟踪JavaScript中的资源。范例

const allWebGL2ContextsResources = new Map();

HTMLCanvasElement.prototype.getContext = function(origFn) {
  return function(type, attribs) {
    const ctx = origFn.call(this, type, attribs);
    if (type === 'webgl2') {
      if (!allWebGL2ContextsResources.has(ctx)) {
        allWebGL2ContextsResources.set(ctx, new Set());
      }
    }
    return ctx;
  };
}(HTMLCanvasElement.prototype.getContext);

const types = ['Buffer', 'Texture', 'Renderbuffer', 'Framebuffer', 'Shader', 'Program', 'Sampler', 'TransformFeedback'];
for (const type of types) {
  const createName = `create${type}`;
  const deleteName = `delete${type}`;

  WebGL2RenderingContext.prototype[createType] = function(origFn) {
    return function(...args) {
      const obj = orignFn.call(this, ...args);
      allWebGL2ContextsResources.get(this).add(obj);
      return obj;
    };
  }(WebGL2RenderingContext.prototype[createType]);

  WebGL2RenderingContext.prototype[deleteType] = function(origFn) {
    return function(obj) {
      const obj = origFn.call(this, obj);
      allWebGL2ContextsResources(this).delete(obj);
    };
  }(WebGL2RenderingContext.prototype[deleteType]);
}

鉴于,当您启动WebAssembly代码时,新的WebGL2上下文将被添加到allWebGL2Contexts,因此您可以先与副本进行比较,然后找到添加的上下文。或更改代码以发出事件或调用回调或发现上下文所需的任何操作。

完成WebAssembly代码后,您可以遍历资源并将其删除。范例

for (const obj of allWebGL2ContextsResources.get(someContext).entries()) {
  for (const type of types) {
    const Type = `WebGL${type}`;
    if (obj instanceof window[Type]) {
      someContext[`delete${type}`](obj);
      continue;
    }
  }
}
allWebGL2ContextsResources.delete(someContext);

否则您可能会失去上下文。参见How do I clean up and unload a WebGL canvas context from GPU after use?

假设您正在使用emscripten,那么另一个选择是emscripten已经跟踪资源,因此您可以modify the emscripten WebGL2 library公开上下文和跟踪,或添加一些清除功能以释放所有被跟踪的内容或丢失上下文。

© www.soinside.com 2019 - 2024. All rights reserved.