2012-08-06 121 views
2

這是對AS3進行BitmapData內存分配的簡單測試。AS3 BitmapData內存泄漏

private function memoryTest(): void 
{ 
    trace("BitmapData memory test. Create bmps..."); // First breakpoint 
    var bmps:Array = new Array (1000); 

    for (var i:int=0; i<1000; i++) 
    { 
    bmps[i] = new BitmapData(451, 451, true, 0); 
    trace(i+". bmp created"); 
    } 

    trace("All bmps created."); // Second breakpoint 

    for (i=0; i<1000; i++) 
    { 
    bmps[i].dispose(); 
    bmps[i] = null; 
    } 
    bmps.splice(0, bmps.length); 
    bmps = null; 

    freeMemoryGC(); 

    trace("All bmps deleted."); 
    trace("Test complete."); // Last breakpoint 
} 

private function freeMemoryGC(): void 
{ 
    // the GC will perform a full mark/sweep on the second call. 
    try 
    { 
    new LocalConnection().connect('foo'); 
    new LocalConnection().connect('foo'); 
    } 
    catch (e:*) 
    { 
    } 

    System.gc(); 
    System.gc(); 
} 

此測試有3個斷點,在代碼中註釋。斷點在一段時間內暫停程序。斷點與此內存狀態圖上的水平線相對應。

memory usage graph

我的問題是:爲什麼不是所有的記憶是後的Dispose()電話免費的嗎?此代碼有什麼問題以及如何清除BitmapData對象?

更新1: 我不認爲這個問題是在垃圾收集器。 dispose()不適用於GC,它應該釋放像素數據。另外這個例子應該分配451 * 451 * 4 * 1000字節理論上。但是這個測試應用程序在System.privateMemory中分配多25%字節,並且這些25%不會被GC和dispose()釋放。

更新2: 如果我創建13張圖片4059x4059像素,而不是100個圖像451x451像素,那麼內存分配恰好等於理論大小和內存調用GC後妥善發佈!我不知道爲什麼會發生。

UPDATE3: 這裏是我的間隔測試,由丹尼爾·梅塞爾在他創造的結果回答: memory usage graph on interval test

+1

運行這個測試100個倍和檢查。我建議你製作間隔並在每一幀上運行。調用GC並不意味着內存將回到相同的狀態。 – turbosqel 2012-08-06 17:48:04

+0

關於100倍時間和間隔的有趣想法。 – Eugene 2012-08-06 22:49:50

+0

你是怎麼調用'memoryTest()'的?除了那個分配內存的函數之外還有什麼東西嗎? – NoobsArePeople2 2012-08-06 23:29:29

回答

0

嘗試,並刪除有關自由memorygc功能本地連接的東西。這是否解決了它?

編輯:

package nyx_gaming_group.as3_tests { 
import flash.display.BitmapData; 
import flash.display.Sprite; 
import flash.system.System; 
import messer_entertainment.MesSerUtils; 

/** 
* ... 
* @author Daniel Dahlkvist 
*/ 
public class BitmapDataMemoryLeak extends Sprite { 
    private var _bitmaps:Array; 

    public function BitmapDataMemoryLeak() { 
     run(); 
    } 

    private function run():void { 
     MesSerUtils.delayCall(createBitmaps, 150); 
     MesSerUtils.delayCall(destroyBitmaps, 4500); 
     MesSerUtils.delayCall(freeMemoryGC, 4700); 
     MesSerUtils.delayCall(run, 8000); 
    } 

    private function createBitmaps():void { 
     trace("BitmapData memory test. Create bmps..."); // First breakpoint 
     _bitmaps = new Array(1000); 

     for (var i:int = 0; i < 1000; i++) { 
      _bitmaps[i] = new BitmapData(451, 451, true, 0); 
     } 

     trace("All bmps created."); // Second breakpoint    
    } 

    private function destroyBitmaps():void { 
     for (var i:int = 0; i < _bitmaps.length; i++) { 
      _bitmaps[i].dispose(); 
      _bitmaps[i] = null; 
     } 
     _bitmaps = null; 

     trace("All bmps deleted."); 
     trace("Test complete."); // Last breakpoint 
    } 

    private function freeMemoryGC():void { 
     System.gc(); 
    } 
} 
} 
+0

我試過了。但沒有本地連接的內存不被清除。 Flash Player 11.1獨立調試器,win32。 – Eugene 2012-08-06 23:07:13

+0

我添加了示例代碼,我如何運行此代碼,對我來說它似乎運行正常?我添加了一些timegaps [在150ms後創建位圖,然後在4500ms後銷燬它們並強制GC在4700ms後運行] – 2012-08-07 13:32:37

+0

您可以在以下位置找到我的結果圖像:http://i48.tinypic。com/m7cc5k.png – 2012-08-07 13:43:22