2014-02-18 4 views
4

мое приложение загружает много сеток. , чтобы избавиться от старых сеток, я пытаюсь их уничтожить. но память никогда не освобождается.освобождение памяти в трёх.js

Я что-то не хватает?

мой простой пример для воспроизведения:

  1. нагрузка 100 больших двоичных сетках
  2. отчуждать все они снова
  3. хром менеджер задач говорит 250MB памяти, то его точно так же, как и без шага 2

    MemTest

    var scene = new THREE.Scene(); 
    var mymesh=Array(); 
    
    // 1. load a lot of geometry/meshes... 
    
    for(var i=0;i<100;i++) 
    { 
        var bloader; 
        bloader = new THREE.BinaryLoader(); 
    
        bloader.load("objekte/presto_6.js" , function(geometry) 
        { 
         mymesh.push(new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color:0xffffff }))); 
         scene.add(mymesh.length-1); 
        }); 
    } 
    
    // 2. try to dispose objects and free memory... 
    
    for(var j=0;j<mymesh.length;j++) 
    { 
        mymesh[j].geometry.dispose(); 
        mymesh[j].material.dispose(); 
        screne.remove(mymesh[j]); 
    } 
    
    mymesh=Array(); 
    
    </script> 
    

ответ

5

Вероятно, опечатка, но если это не так: screne.remove(mymesh[j]); должен быть scene.remove(mymesh[j]);

Кроме того: Rember (или узнать), как JS управляет Память. Его сборщик мусора - это очистка и очистка GC. Это флаги объекты, которые не упоминаться в любом месте, а затем чистит их в следующий раз ГХ пинков в:

for(var j=0;j<mymesh.length;j++) 
{ 
    mymesh[j].geometry.dispose(); 
    mymesh[j].material.dispose(); 
    scene.remove(mymesh[j]); 
} 

mymesh массива все еще содержит ссылки на объекты сетки вы attemting бесплатно. GC видит этот referenec и поэтому воздерживается от пометок этих объектов. Переназначение, удалять, либо весь массив этих конкретных ключей вам больше не нужно:

for(var j=0;j<mymesh.length;j++) 
{ 
    mymesh[j].geometry.dispose(); 
    mymesh[j].material.dispose();//don't know if you need these, even 
    scene.remove(mymesh[j]); 
    mymesh[j] = undefined;//or 
    delete(mymesh[j]); 
} 
//or simply: 
mymesh = undefined;//or some other value 

Это позволяет память будет освобождена, если другая переменная остается в области, которая ссылается на некоторые или все из этих объектов тоже.
Как asside:

mymesh=Array(); 

Является ли плохой код на многих уровнях. Функции JS, которые начинаются с UpperCase, являются конструкторами и должны быть названы usign ключевое слово new, хотя большинство конструкторов (особенно нативные объекты) shoul можно назвать как можно больше.
Их поведение может быть непредсказуемым, и часто более короткий путь, чтобы написать код:

mymesh = [];//an array literal 
//example of werird behaviour: 
mymesh = new Array(10);//[undefined, undefined, undefined....] 
mymesh = [10]; 
mymesh = new Array('10');//['10'] 
mymesh = new Array(1.2);//RangeError 
var o = new Object(123);//returns new Nuber 
o = new Object('something');//new String 
o = new Object(false);//new Boolean 
o = new Object('foo', 'bar');//new String('foo')!!! 
o = {foo: 'bar'};//<-- this is soooo much easier 
+1

мой следующий вопрос будет, если можно просто удалить данные вершин/граней/нормалей и т.д., когда он был загружен к gpu. Я знаю, что есть geometry.dynamic = false; но данные вершин все еще там, я считаю. могу ли я освободить эту память тоже? если я попробую что-то вроде «zmesh.geometry.vertices = undefined;» threejs не может получить доступ к .length этого массива. – seattledirk

+0

@pandrr: Конечно, если вы присваиваете 'undefined' тому, что затем используется как массив, вы фактически делаете' undefined.length', что невозможно. Вы можете попробовать 'zmesh.geometry.vertices = []'. Howeve: JS - собранный мусор: у вас есть _no real control_ над памятью.Если вы хотите самостоятельно управлять каждым байтом памяти, вам нужно написать C :). Простую вещь, которую вы можете сделать, чтобы помочь GC - не использовать глобальную область, просто напишите '(function() {' на первом строка вашего скрипта и добавьте '}());' в конце и _declare каждый var_ –

+0

уверен, что это логично, что это не работает. это был более трехзначный вопрос, если можно выпустить эти данные, потому что он уже был сохранен на gpu и не будет изменен, поэтому нет необходимости обращаться к нему снова. – seattledirk

Смежные вопросы