在three.js中释放内存

sea*_*irk 4 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>
    
    Run Code Online (Sandbox Code Playgroud)

Eli*_*gem 8

可能是一个错字,但如果不是: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]);
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

mymesh=Array();
Run Code Online (Sandbox Code Playgroud)

是很多级别的错误代码.以UpperCase开头的JS函数是构造函数,应该调用usign 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
Run Code Online (Sandbox Code Playgroud)