在three.js中释放内存

时间:2014-02-18 10:44:59

标签: javascript memory three.js

我的应用程序加载了很多网格物体。 摆脱旧网格我试图处理它们。但记忆永远不会被释放。

我错过了什么吗?

我复制的简单例子:

  1. 加载100个大二进制网格
  2. 再次处理所有这些
  3. chrome任务管理器说使用了250mb的内存,它与没有第2步的内存完全相同

        MEMTEST                    

    var scene = new THREE.Scene();
    var mymesh=Array();
    
    // 1. load a lot of geometry/meshes...
    
    for(var i=0;i<100;i++)
    {
        var bloader;
        bloader = new THREE.BinaryLoader();
    
        bloader.load( "objekte/presto_6.js" , function( geometry ) 
        {
            mymesh.push(new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( {color:0xffffff } ) ));
            scene.add(mymesh.length-1);
        });
    }
    
    // 2. try to dispose objects and free memory...
    
    for(var j=0;j<mymesh.length;j++)
    {
        mymesh[j].geometry.dispose();
        mymesh[j].material.dispose();
        screne.remove(mymesh[j]);
    }
    
    mymesh=Array();
    
    </script>
    

1 个答案:

答案 0 :(得分:7)

可能是拼写错误,但如果不是:screne.remove(mymesh[j]);应为scene.remove(mymesh[j]);

除此之外:rember(或找出)JS如何管理内存。它的垃圾收集器是一个扫描和清洁GC。它会标记未在任何地方引用的对象,然后在GC启动时清除它们:

for(var j=0;j<mymesh.length;j++)
{
    mymesh[j].geometry.dispose();
    mymesh[j].material.dispose();
    scene.remove(mymesh[j]);
}

mymesh数组仍然包含对您要释放的网格对象的引用。 GC看到了这个参考,因此避免标记这些对象。重新分配,删除您不再需要的那些特定键的整个数组:

for(var j=0;j<mymesh.length;j++)
{
    mymesh[j].geometry.dispose();
    mymesh[j].material.dispose();//don't know if you need these, even
    scene.remove(mymesh[j]);
    mymesh[j] = undefined;//or
    delete(mymesh[j]);
}
//or simply:
mymesh = undefined;//or some other value

这允许释放内存,除非另一个变量保留在引用部分或全部这些对象的范围内。
作为助手:

mymesh=Array();

许多级别的代码都不好。以UpperCase开头的JS函数是构造函数,并且应该调用new关键字,尽管大多数构造函数(尤其是本机对象)应尽可能少地调用。
他们的行为可能无法预测,编写代码的方式通常较短:

mymesh = [];//an array literal
//example of werird behaviour:
mymesh = new Array(10);//[undefined, undefined, undefined....]
mymesh = [10];
mymesh = new Array('10');//['10']
mymesh = new Array(1.2);//RangeError
var o = new Object(123);//returns new Nuber
o = new Object('something');//new String
o = new Object(false);//new Boolean
o = new Object('foo', 'bar');//new String('foo')!!!
o = {foo: 'bar'};//<-- this is soooo much easier