三个js正确从场景中删除对象(仍然在HEAP中保留)

时间:2016-06-11 11:02:06

标签: javascript three.js

删除网格表单场景的正确方法是什么? 在这个例子中:

    removable_items = [];
    box = new THREE.Object3D();
    scene.add(box);

    function add() {
        var mesh = new THREE.Mesh( new THREE.IcosahedronGeometry( 10, 5 ), new THREE.MeshPhongMaterial( {color: 0xFFFFFF}) );   
        box.add( mesh );
        removable_items.push(mesh);
        //clean(); ///// when is integrated in function memory is cleaned properly
    }   

    function clean() {
          if( removable_items.length > 0 ) {
            removable_items.forEach(function(v,i) {
               v.parent.remove(v);
            });
            removable_items = null;
            removable_items = [];
          }
    }

    function makeExperiment(r) {
      var i = 0;
      while (i < r) {
        add();
        i++;
        if( r === i ) console.log(r+' finnished ');
      }
    }

makeExperiment(50);

///之后我mannualy设置clean();

网格物体在场景中不再可见,正如预期的那样,但是使用内存,在一段时间后内存泄漏和浏览器崩溃完成。

问题在哪里,THREE.js做了其他一些参考吗?

THREE.js R73

编辑:当clean();集成在函数中时(现在在代码中注释),内存将被正确清理。但是,在clean();完成后手动设置makeExperiment();时,内存未设置为空闲。

1 个答案:

答案 0 :(得分:18)

我已经完成了一些实验,并且认为您的代码没有任何问题。我已经了解到的一件事是,垃圾收集器可能无法在您认为的情况下完全运行。为了以防万一,我将您的代码包装在IIFE中(良好实践,但在这种情况下不是必需的)并且期望在函数完成运行并且超出范围后立即清除堆。但它实际上需要一些时间来澄清:

clean 50

所以我想,好吧,那不是很好,如果我在垃圾收集器只是挥之不去的那个时间盘内创造了更多的对象,那么我做了:

.
.
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();

这就是发生的事情:

clean 400

垃圾收集器似乎正在执行其工作,并且您正在为此目的正确删除它们。 然而,您可能正在使用THREE.js渲染器,如果我理解正确,渲染器会保留对材质,几何和纹理的引用。因此,如果没有正确处理它们,它们将不会被垃圾收集。 THREE.js有Geometry s,MaterialTexture s .dispose()的方法,它会通知渲染器将其删除。这就是我改变clean()函数的方法:

removable_items.forEach(function(v,i) {
  v.material.dispose();
  v.geometry.dispose();
  box.remove(v);
});