Javascript 三个js从场景中移除对象(仍保留在堆中)
从场景中移除网格的正确方法是什么? 在本例中:Javascript 三个js从场景中移除对象(仍保留在堆中),javascript,three.js,Javascript,Three.js,从场景中移除网格的正确方法是什么? 在本例中: removable_items = []; box = new THREE.Object3D(); scene.add(box); function add() { var mesh = new THREE.Mesh( new THREE.IcosahedronGeometry( 10, 5 ), new THREE.MeshPhongMaterial( {color: 0xFFFFFF}) );
removable_items = [];
box = new THREE.Object3D();
scene.add(box);
function add() {
var mesh = new THREE.Mesh( new THREE.IcosahedronGeometry( 10, 5 ), new THREE.MeshPhongMaterial( {color: 0xFFFFFF}) );
box.add( mesh );
removable_items.push(mesh);
//clean(); ///// when is integrated in function memory is cleaned properly
}
function clean() {
if( removable_items.length > 0 ) {
removable_items.forEach(function(v,i) {
v.parent.remove(v);
});
removable_items = null;
removable_items = [];
}
}
function makeExperiment(r) {
var i = 0;
while (i < r) {
add();
i++;
if( r === i ) console.log(r+' finnished ');
}
}
makeExperiment(50);
removable_items=[];
box=new THREE.Object3D();
场景。添加(框);
函数add(){
var mesh=新的三点网格(新的三点二十面体几何(10,5),新的三点网格材质({color:0xFFFFFF}));
框。添加(网格);
可拆卸物品。推(网);
//clean();///when集成在函数内存中时,是否正确清理
}
函数clean(){
如果(可移动项目长度>0){
可拆卸的物品。forEach(功能(v,i){
v、 移除(v);
});
可移动_项=空;
可拆卸_项目=[];
}
}
函数生成实验(r){
var i=0;
while(i
///然后我手动设置clean()代码>
网格不再像预期的那样在场景中可见,而是使用内存,一段时间后,内存泄漏和浏览器崩溃将结束
问题出在哪里?THREE.js是否进行了其他引用
3.js R73
EDIT:when是clean()代码>集成在函数中(现在在代码中注释)内存已正确清理。但是当我设置clean()代码>在makeExperiment()之后手动执行代码>已完成,内存未设置为可用。
我做了一些实验,我认为您的代码没有什么问题。不过,我学到的一件事是,垃圾收集器可能不会完全按照您认为的方式运行。以防万一,我将您的代码包装在一个IIFE中(良好实践,但在本例中不是必需的),并期望在函数完成运行并超出范围后立即清除堆。但事实上,它需要一些时间来澄清:
所以我想,好吧,这不太好,如果我在垃圾收集器停留的时间跨度内创建更多的对象会怎么样,所以我做了:
.
.
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
事情就是这样:
垃圾收集器似乎正在完成它的工作,为此,您正在正确地删除它们但是,您可能也在使用THREE.js渲染器,如果我理解正确,渲染器会保留对材质、几何体和纹理的引用。因此,如果没有正确处理这些垃圾,它们将不会被垃圾收集。THREE.js有一个用于几何体
s、材质
s和纹理
s的方法,称为.dispose()
,它也会通知渲染器将其删除。这就是我如何更改您的clean()
函数的方法:
removable_items.forEach(function(v,i) {
v.material.dispose();
v.geometry.dispose();
box.remove(v);
});
我在看这个--你用什么程序/工具来检查内存?你的陈述<代码>新的三。二十面体几何(1,5)代码>第二个参数是细节。将其作为5进行大量处理。这是你想要回答的问题的一部分吗?默认值为1。为了清楚地说明内存示例,我使用了高细节网格。JSON或OBJ模型或长方体几何体也存在同样的问题,只需要更长时间重复MakeExperience函数。我正在使用chrome控制台和chrome内存快照。是否确实v.parent.remove(v)代码>将按预期工作?是的,当我设置框时没有区别。删除(v)hi和thx!正如我在图中看到的,删除操作仍然会将数据留在堆中,当我进行数千次此实验时,它将导致浏览器无响应。我在游戏中使用这种情况,需要重新加载新对象(敌人)并移除旧对象-死亡。您是否在add()函数中使用了integratedclean()函数?(在我的代码中注释了行)或者您在延迟了一段时间后手动运行了clean()。@Martin我尝试在add()
函数内部进行清理,并在makeExperiment()
之后手动进行清理(如上所示)。您无法准确控制浏览器垃圾回收器何时决定清理,如果希望清除某个变量,您所能做的就是删除它的所有引用。当在add()
内部调用clean()
时,垃圾收集器仍然没有清理堆50次,只有大约6次,因此这是相同的行为。浏览器无响应的原因是因为javascript是单线程的,而您正在使用该线程执行1000次操作。尝试在多个帧上分割它