Javascript 释放three.js中的内存

Javascript 释放three.js中的内存,javascript,memory,three.js,Javascript,Memory,Three.js,我的应用程序加载了很多网格。 为了摆脱旧的网格,我尝试处理它们。但是内存永远不会被释放 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/p

我的应用程序加载了很多网格。 为了摆脱旧的网格,我尝试处理它们。但是内存永远不会被释放

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>
我错过什么了吗

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>
我的简单复制示例:

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>
  • 加载100个大的二进制网格
  • 再把它们全部处理掉
  • chrome任务管理器表示使用了250mb内存,与没有步骤2时完全相同

    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>
    
    记忆测验

    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>
    
    var scene=new THREE.scene();
    var mymesh=Array();
    // 1. 加载大量几何体/网格。。。
    
    对于(var i=0;i可能是一个输入错误,但如果不是:
    screne.remove(mymesh[j]);
    应该是
    scene.remove(mymesh[j]);

    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>
    
    除此之外:记住(或找出)JS是如何管理内存的。它的垃圾收集器是一个扫描清理GC。它标记没有在任何地方被引用的对象,然后在下次GC启动时清理它们:

    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>
    
    for(var j=0;j<mymesh.length;j++)
    {
        mymesh[j].geometry.dispose();
        mymesh[j].material.dispose();
        scene.remove(mymesh[j]);
    }
    
    这允许释放内存,除非另一个变量也在引用部分或所有这些对象的作用域中。
    作为助手:

    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>
    
    mymesh=Array();
    
    在许多级别上都是糟糕的代码。以大写字母开头的JS函数是构造函数,应该使用
    new
    关键字调用,尽管大多数构造函数(尤其是本机对象)应该尽可能少地调用。
    他们的行为可能是不可预测的,通常有一种较短的方式来编写代码:

    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>
    
    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
    
    mymesh=[];//数组文本
    //werird行为示例:
    mymesh=新数组(10);//[未定义,未定义,未定义….]
    mymesh=[10];
    mymesh=新数组('10');//['10']
    mymesh=新数组(1.2);//范围错误
    var o=new Object(123);//返回新的数字
    o=新对象('something');//新字符串
    o=新对象(false);//新布尔值
    o=新对象('foo','bar');//新字符串('foo')!!!
    
    o={foo:'bar'};//我的下一个问题是,上传到gpu时,是否可以删除顶点/面/法线等数据。我知道有geometry.dynamic=false;但我相信顶点数据仍然存在。我可以释放内存吗?如果我尝试类似“zmesh.geometry.vertics=undefined;”threejs无法访问此数组的.length。@pandrr:当然,如果您将
    未定义的
    指定给某个然后用作数组的对象,则实际上是在执行
    未定义的.length
    ,这是不可能的。您可以尝试
    zmesh.geometry.vertics=[]
    .Howeve:JS是垃圾收集的:您对内存没有真正的控制权。如果您想自己管理内存的每个字节,您必须编写C:)帮助GC的一个简单方法是不使用全局作用域,只需在脚本的第一行编写
    (function(){
    ,然后添加
    }())并声明每个变量,确保其逻辑性不起作用。这更像是一个3JS问题,如果有可能释放数据,因为它已经存储在gpu上,不会被更改,所以不需要再次访问它。@seattledirk:对此我不确定,我倾向于说不,这是不可能的。由于JS是一种高级语言,因此您在内存管理方面没有真正的发言权:如果数据存储在GPU上,那么运行代码的线程将管理资源,而不是代码。该线程仍将以某种方式保留数据。如果要真正释放内存,内核将可以自由使用存储数据的内存,因此它可能会在接下来的2毫秒内被覆盖。