2014-02-18 61 views
4

我的應用程序加載了很多網格。 擺脫舊的網格我嘗試處置它們。但內存永遠不會被釋放。釋放three.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。這是不被任何地方引用,然後清除它們下一次GC踢標誌物:

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

mymesh陣列仍包含對你attemting釋放網格對象的引用。 GC看到這個參考文獻,因此避免標記這些對象。重新分配,刪除,要麼這些特定鍵的整個數組,你不再需要:

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

是在許多層面上糟糕的代碼。以UpperCase開頭的JS函數是構造函數,應該叫做使用new關鍵字,儘管大多數構造函數(尤其是本地對象)只能被調用。
他們的行爲是不可預知的,而且也經常寫代碼更短的方式:

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。 我知道有幾何。動態=假;但頂點數據仍然存在我相信。我可以釋放那個記憶嗎?如果我嘗試像「zmesh.geometry.vertices = undefined;」 threejs不能訪問這個數組的長度。 – seattledirk

+0

@pandrr:當然,如果你將'undefined'賦值給一個被用作數組的東西,那麼你實際上正在做'undefined.length',這是不可能的。你可以試試'zmesh.geometry.vertices = []'。 Howeve:JS是垃圾收集:你對內存沒有真正的控制權。如果你想自己管理每一個字節的內存,你必須編寫C :)你可以做一件簡單的事情來幫助GC不用全局作用域,只需在第一個函數中寫入'(function(){'你的腳本的行,並添加'}());'最後,_declare每var_ –

+0

肯定它的邏輯,這是行不通的。它更像是一個3js的問題,如果可以釋放該數據,因爲它已經存儲在gpu中並且不會被改變,所以不需要再次訪問它。 – seattledirk