2012-08-06 69 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