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>
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毫秒内被覆盖。