2014-01-05 3 views
5

У нас есть приложение, которое использует THREE.js для рендеринга трехмерных изображений телесных сеток. У нас есть объект, называемый MeshViewer, который инкапсулирует функциональность рендеринга; при методе инициализации, мы устанавливаемСбор мусора THG.js webGL

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

Мы написали сценарий, чтобы проверить, что this.renderer не быть высвобождены.

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

В этом случае, «mesh_viewer» является идентификатором элемента DOM, который мы хотим внедрить зритель. Наш метод очистки устанавливает

this.renderer = null 

Cleanup работает, в том смысле, что если мы не «Выполняем очистку, мы получаем ошибку, когда существует слишком много активных контекстов WebGL, и мы больше не можем их создавать, и если мы очищаем, мы не получаем эту ошибку.

Мой вопрос: почему это происходит, если viewer.cleanup вызывается прямо перед циклом в setTimeout и передается, когда очистка вызывается снаружи и перед setTimeout? (Это может быть вопрос JavaScript больше, чем вопрос THREE.js/WebGL.)

+2

Почему этот вопрос был остановлен? – yangmillstheory

+0

Есть ли какие-либо ошибки в консоли? –

+0

Возможно, функция, переданная в 'setTimeout', захватывает средство просмотра и все его свойства, включая средство визуализации, что означает, что счетчик ссылок рендеринга никогда не переходит в 0 и, следовательно, не собирает мусор? –

ответ

0

Возможно, это связано с the way a browser executes javascript and other stuff in a single thread.

Если вы положили viewer.cleanup(); до setTimeout, либо внутренняя функция браузера, либо функция отложенного режима THREE найдут время, чтобы фактически освободить рендер до вызова loop();.

Else viewer.cleanup(); и loop() будут называться последовательно, без какого-либо промежутка времени для чего-либо еще.

примечание: Я не делал каких-либо тест, чтобы подтвердить, что


Также предложение: может быть, вы должны поставить THREE.WebGLRenderer экземпляр в одноэлементных и использовать его вместо того, чтобы выпустить его.