Threejs废置对象避免内存泄漏(How to dispose of objects)

925 阅读2分钟

为了提高性能,并避免应用程序中的内存泄露,一个重要的方面是废置未使用的类库实体。 每当你创建一个three.js中的实例时,都会分配一定数量的内存。然而,three.js会创建在渲染中所必需的特定对象, 例如几何体或材质,以及与WebGL相关的实体,例如buffers或着色器程序。 非常值得注意的是,这些对象并不会被自动释放;相反,应用程序必须使用特殊的API来释放这些资源。

上面是threejs官方对于废置对象的说明,最近在研究threejs内存泄漏相关的问题,文档中说到对于已经创建并且未使用到的几何体(geometry)及材质(material)并不会自动废除,因为材质和几何体是可以全局复用的,threejs并不知道用户何时需要销毁,也就是说当移除场景中的对象时,对象相应的几何体,材质,纹理等就需要我们手动删除,否则会继续占用内存空间,有内存泄漏的隐患,严重时会拉垮整理页面导致浏览器崩溃。

查看渲染器中geometry数量

销毁几何体首先要查看当前渲染器的几何本数量,threejs提供了查看当前渲染器包括几何体,纹理统计等信息的api WebGLRenderer.info,我们可以利用这个接口调试几何体移除操作,控制台打印renderer.info查看:

console.log(renderer.info)

输出结构如下,其中memory.geometries是当前渲染器中几何体的统计数量:

几何体和材质销毁

通过方法object.geometry.dispose(),可以实现几何体销毁,函数如下:

/**
 ** @param {object} obj 需要销毁的对象 
*/
function disposeObj(obj) {
  if (!obj) return;
  // .traverse(callback: Function)
  // 遍历对象及所有后代对象
  obj.traverse(function (obj) {
    // 废置几何体及材质
    if (obj.geometry) {
      obj.geometry.dispose();
    }
    if (obj.material) {
      obj.material.dispose();
    }
  });
  // 场景中移除对象
  scene.remove(obj);
}

// 执行dispose函数移除并销毁对象
disposeObj(mesh);

执行函数后,重新查看renderer.info中的memory.geometries的数量是否同时减少,如减少表示当前几何体销毁成功,如图:

参考:threejs官方关于废置对象方法及常见问题