Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
384 views
in Technique[技术] by (71.8m points)

javascript - THREE js proper removing object from scene (still reserved in HEAP)

What is the proper way to remove mesh form scene? In this example:

    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);

/// after that i mannualy set clean();

meshes are not visible at scene anymore, as expected, but sill using memory, which after some time finish with memory leak and browser crash.

Where is the problem, did THREE.js making some other references?

THREE.js R73

EDIT: when is clean(); integrated in function (commented now in code) memory is cleaned properly. But when I set clean(); manually after makeExperiment(); is done, memory is not set as free.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've done a few experiments and i think there is nothing really wrong with your code. One thing that i've learned though, is that that garbage collector might not run exactly when you think it does. Just in case, I wrapped your code in a IIFE (good practice but not necessary in this case) and expected the heap to be cleared as soon as the function finished running and went out of scope. But it actually took some time for it to clear:

clean 50

So i thought, okey, thats not to good, what if i was creating more objects in that timespan where the garbage collector is just lingering, so i did:

.
.
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();
makeExperiment(50);
clean();

and this is what happened:

clean 400

The garbage collector seems to be doing its job, and you are deleting them correctly for this purpose. However, You are probably using THREE.js Renderer aswell, and if I understand it correctly, the Renderer keeps references to materials, geometries and textures. So if these are not disposed of correctly, they will not be garbage collected. THREE.js has a method for Geometrys, Materials and Textures called .dispose() which will notify the Renderer to remove it aswell. So this is how I would change your clean() function:

removable_items.forEach(function(v,i) {
  v.material.dispose();
  v.geometry.dispose();
  box.remove(v);
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...