2014-01-05 17 views
5

Wir haben eine App, die THREE.js verwendet, um 3D-Bilder von Körper Meshes zu rendern. Wir haben ein Objekt namens MeshViewer, das die Rendering-Funktionalität kapselt; während der initialize Methode setzen wirTHREE.js webGL Garbage Collection

this.renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true }) 

Wir haben ein Skript geschrieben zu testen, dass this.renderer nicht freigegeben werden.

<script> 
    var count = 0; 
    function loop() { 
     if (count >= 25) { 
      return; 
     } 
     else { 
      count++; 
      var viewer = new MeshViewer(
       'mesh_viewer', 
       's3_assets/textured_mean_scape_female.obj', 
       [] 
      ); 

      viewer.cleanup(); 

      setTimeout(function() { 
       loop(); 
      }, 500); 
     } 
    } 
    loop(); 
</script> 

In diesem Fall 'mesh_viewer' ist die ID des Elements DOM wir den Betrachter in einbetten möchten. Unsere Cleanup Methode setzt

this.renderer = null 

Cleanup arbeitet, in dem Sinne, dass, wenn wir don Wenn wir keine Bereinigung durchführen, erhalten wir einen Fehler, dass zu viele aktive WebGL-Kontexte existieren, und wir können nicht mehr erstellen, und wenn wir aufräumen, erhalten wir diesen Fehler nicht.

Meine Frage ist, warum scheitert dies, wenn viewer.cleanup direkt vor loop in setTimeout aufgerufen wird, und übergeben, wenn Bereinigung außerhalb und vor setTimeout aufgerufen wird? (Dies kann eine JavaScript-Frage sein mehr als eine THREE.js/WebGL Frage.)

+2

Warum wurde diese Frage abgelehnt? – yangmillstheory

+0

Gibt es Konsolenfehler? –

+0

Vielleicht erfasst die Funktion 'setTimeout' den Viewer und alle seine Eigenschaften, einschließlich des Renderers, was bedeutet, dass die Referenzzählung des Renderers niemals auf 0 geht und somit keine Garbage Collection stattfindet. –

Antwort

0

Es ist wahrscheinlich im Zusammenhang mit the way a browser executes javascript and other stuff in a single thread.

Wenn Sie viewer.cleanup(); vor setTimeout setzen, wird entweder eine interne Browserfunktion oder eine DREI defered-Funktion Zeit finden, den Renderer vor dem Aufruf von loop(); tatsächlich freizugeben.

Else viewer.cleanup(); und loop() werden fortlaufend aufgerufen, ohne dass dazwischen etwas passiert.

Anmerkung: Ich habe keine Test durchführen, um zu bestätigen, dass


Auch ein Vorschlag: Vielleicht sollten Sie Ihre THREE.WebGLRenderer Instanz in eine Singleton setzen und sie wiederverwenden, anstatt sie zu veröffentlichen.