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次操作。尝试在多个帧上分割它