三个js正确从场景中删除对象(仍然在HEAP中保留)

Mar*_*tin 15 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}) );   
        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);
Run Code Online (Sandbox Code Playgroud)

///之后我mannualy设置 clean();

正如预期的那样,网格在场景中不可见,但是使用内存,在一段时间内完成内存泄漏和浏览器崩溃.

问题在哪里,THREE.js做了一些其他的参考?

THREE.js R73

编辑:何时clean();集成在函数中(现在在代码中注释)内存被正确清理.但是当我完成clean();手动设置后makeExperiment();,内存不会被设置为空闲.

mic*_*nil 19

我做了一些实验,我认为你的代码没有什么问题.我学到的一件事是,垃圾收集器可能无法在您认为的情况下完全运行.为了以防万一,我将您的代码包装在IIFE中(良好实践,但在这种情况下不是必需的)并且期望在函数完成运行并且超出范围后立即清除堆.但它确实需要一些时间才能清除:

干净50

所以我想,好吧,那不是很好,如果我在垃圾收集器只是挥之不去的那个时间盘内创造了更多的对象,那么我做了:

.
.
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
Run Code Online (Sandbox Code Playgroud)

这就是发生的事情:

干净400

垃圾收集器似乎正在完成它的工作,你正在为此正确地删除它们.但是,您可能正在使用THREE.js Renderer,如果我理解正确,Renderer会保留对材质,几何和纹理的引用.因此,如果没有正确处理它们,它们将不会被垃圾收集.THREE.js有一个Geometrys,Materials和Textures 方法,.dispose()它会通知渲染器将其删除.这就是我改变你的clean()功能的方法:

removable_items.forEach(function(v,i) {
  v.material.dispose();
  v.geometry.dispose();
  box.remove(v);
});
Run Code Online (Sandbox Code Playgroud)