我的应用程序加载了很多网格。 为了摆脱旧的网格,我尝试处理它们。但内存永远不会被释放。
我错过了什么吗?
我的复制简单示例:
- 加载 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>
最佳答案
可能是打字错误,但如果不是:screne.remove(mymesh[j]);
应该是 scene.remove(mymesh[j]);
除此之外:记住(或找出)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 看到这个 referenec,因此避免标记这些对象。重新分配、删除您不再需要的那些特定键的整个数组:
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
关键字调用,尽管大多数构造函数(尤其是 native 对象)应该尽可能少地调用。
它们的行为可能是不可预测的,并且通常有更短的代码编写方式:
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
关于javascript - 在 three.js 中释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21851349/