2016-06-11 5 views
11

Was ist der richtige Weg, um Mesh Form Szene zu entfernen? In diesem Beispiel:DREI js richtig Entfernen von Objekt aus Szene (immer noch in HEAP reserviert)

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

/// danach i mannualy clean(); gesetzt

Maschen in Szene nicht mehr sichtbar sind, wie erwartet, aber Schweller Speicher verwendet, die nach einiger Zeit fertig mit Speicherleck und Browser-Absturz.

Wo ist das Problem, hat THREE.js einige andere Referenzen gemacht?

Three.js R73

EDIT: clean(); wenn in Funktion (kommentierten nun in Code) -Speicher integriert ist richtig gereinigt. Aber wenn ich clean(); manuell nach makeExperiment(); eingestellt habe, wird der Speicher nicht als frei gesetzt.

+0

Ich bin Blick auf diese - was für Programm/Tool verwenden Sie im Speicher suchen? – dcromley

+0

Ihre Aussage 'neue THREE.IcosahedronGeometry (1, 5)' Der 2. Parameter ist Detail. Es als 5 zu haben macht viel Verarbeitung. Ist das der Teil Ihres Problems, den Sie beantwortet haben möchten? Der Standardwert ist 1. – dcromley

+0

Ich benutze hohe Detail Mesh aus Gründen, um das Speicherbeispiel deutlich zu veranschaulichen. Es ist das gleiche Problem mit den JSON- oder OBJ-Modellen oder der Box-Geometrie, nur die makeExperiment-Funktion muss länger wiederholt werden. Ich verwende Chrome-Konsole und Chrome-Speicher-Snapshot. – Martin

Antwort

15

Ich habe ein paar Experimente gemacht und ich denke gibt es nichts wirklich falsch mit Ihrem Code. Eine Sache, die ich jedoch gelernt habe, ist, dass dieser Müllsammler möglicherweise nicht genau ausgeführt wird, wenn du denkst, dass dies der Fall ist. Nur für den Fall, ich wickelte Ihren Code in eine IIFE (gute Praxis, aber nicht notwendig in diesem Fall) und erwartet, dass der Heap gelöscht werden, sobald die Funktion ausgeführt wurde und ging aus dem Geltungsbereich. Aber es einige Zeit tatsächlich dauerte es deutlich zu:

clean 50

Also dachte ich, okey, das ist nicht zu gut, was ist, wenn ich war mehr Objekte in diesem Zeitraum schaffen, in dem der Garbage Collector nur verweilen, so ich tat:

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

und das ist, was passiert ist:

clean 400

Der Müll c ollector scheint seine Aufgabe zu erledigen, und Sie löschen sie für diesen Zweck korrekt. Allerdings, Sie verwenden wahrscheinlich auch THREE.js Renderer, und wenn ich es richtig verstehe, behält der Renderer Verweise auf Materialien, Geometrien und Texturen. Also, wenn diese nicht richtig entsorgt werden, werden sie nicht Müll gesammelt. THREE.js hat eine Methode für Geometry s, Material s und Texture s genannt .dispose(), die den Renderer benachrichtigt, um es auch zu entfernen. Das ist also, wie ich Ihre clean() Funktion ändern:

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

hi und thx!Wie ich in Ihrem Diagramm sehe, bleiben beim Entfernen Daten im Heap. Wenn ich dieses Experiment tausende Male mache, reagiert der Browser nicht mehr. Ich benutze diese Situation im Spiel, und es besteht ein großer Bedarf, neue Objekte (Feinde) neu zu laden und alte - Todesfälle zu entfernen. Haben Sie es mit der integrierten Funktion clean() in der Funktion add() probiert? (Kommentarzeile in meinem Code) oder hast du nach einiger Zeitverzögerung clean() manuell ausgeführt? – Martin

+1

@Martin Ich habe versucht, innerhalb der 'add()' Funktion und manuell nach dem 'makeExperiment()' (wie oben gesehen) zu reinigen. Sie können nicht genau steuern, wann der Garbage Collector des Browsers beschließen soll, zu bereinigen. Wenn Sie möchten, dass eine Variable gelöscht wird, können Sie nur alle Referenzen davon entfernen. Beim Aufrufen von 'clean()' innerhalb von 'add()' löschte der Garbage-Collector den Heapspeicher noch 50 Mal, nur etwa 6 Mal, also war es das gleiche Verhalten. Der Grund, warum der Browser nicht reagiert, liegt darin, dass JavaScript ein Singlethread ist und Sie diesen Thread verwenden, um 1000 Mal etwas zu tun. Versuchen Sie, es auf mehrere Frames aufzuteilen – micnil

Verwandte Themen