ТРЕХ js надлежащее удаление объекта из сцены (все еще зарезервировано в HEAP)

Каков правильный способ удаления сцены из сетки? В этом примере:

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

///после этого я mannualy set clean();

сетки больше не видны на сцене, как и ожидалось, но с использованием памяти, которая через некоторое время заканчивается утечкой памяти и сбоем браузера.

Где проблема, сделал ли THREE.js некоторые другие ссылки?

THREE.js R73

EDIT: когда функция clean(); интегрирована в функцию (прокомментировано сейчас в коде), память очищается должным образом. Но когда я устанавливал clean(); вручную после завершения makeExperiment();, память не устанавливается как свободная.

Ответ 1

Я сделал несколько экспериментов, и я думаю нет ничего плохого в вашем коде. Одна вещь, которую я узнал, заключается в том, что сборщик мусора может не работать точно, когда вы думаете, что это так. На всякий случай, я завернул ваш код в IIFE (хорошая практика, но не обязательно в этом случае), и ожидал, что куча будет очищена, как только функция завершит работу и выйдет за рамки. Но на это потребовалось некоторое время, чтобы очистить:

clean 50

Итак, я думал, okey, thats not to good, что, если бы я создавал больше объектов в этот промежуток времени, когда сборщик мусора просто задерживался, поэтому я сделал:

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

и вот что произошло:

clean 400

Кажется, что сборщик мусора выполняет свою работу, и вы правильно их удаляете для этой цели. Тем не менее. Вероятно, вы также используете TREE.js Renderer, и если я правильно его понимаю, Renderer сохраняет ссылки на материалы, геометрию и текстуры. Поэтому, если они не утилизируются правильно, они не будут собираться мусором. THREE.js имеет метод для Geometry s, Material и Texture, называемый .dispose(), который уведомит Renderer о его удалении. Таким образом, я бы изменил вашу функцию clean():

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