AS3在BitmapData内存上绘制Sprite内存泄漏

时间:2017-11-07 11:50:50

标签: actionscript-3 flash memory-leaks air

我有一个AIR应用程序,可以从Flash编辑器中呈现图像。您可以自定义多个曲面 - 它们都具有相同的宽度和高度。然后,每个表面都由AIR应用程序呈现。

我正在努力解决内存泄漏问题。我无法解决。

对于我需要渲染的每个表面,我有一个包含许多组件的Sprite(其他精灵 - 一些有事件侦听器,BitmapDatas和其他子组件,sprite等)。

我已经知道要将垃圾收集的BitmapData问题,我测试了两个:

  • 为每个渲染创建一个新的BitmapData,然后dispose()并指向null
  • 为每次渲染重用单个BitmapData

内存泄漏仍然按比例发生。

这是我的循环:

var bm:BitmapData = new BitmapData(destDim.x, destDim.y, true, bgColor);
var mtx:Matrix = new Matrix();
trace('before drawing :'+(System.privateMemory/1024));
bm.draw(myBigSprite, mtx, null, null, null, true);
trace('after drawing :'+(System.privateMemory/1024));
var result:Bitmap = new Bitmap(bm, PixelSnapping.NEVER, true);

//return result and encode Bitmap to png

result.bitmapData.dispose();
result.bitmapData = null;
result = null;

结果:

before drawing :208364
after drawing :302816
Wrote bitmap to file: surface0.png
before drawing :303296 
after drawing :446160 
Wrote bitmap to file: surface1.png 
before drawing :446160
after drawing :565212
Wrote bitmap to file: surface2.png 
before drawing :565924
after drawing :703100 
Wrote bitmap to file: surface3.png 
before drawing :703572
after drawing :834420 
Wrote bitmap to file: surface4.png 

我觉得我在绘制函数行为中缺少某些东西。看起来我新创建的myBigSprite组件的实例在绘制操作后仍然存在。

我试图在每个循环结束时完全破坏myBigSprite,它不会改变任何东西......

任何提示都将不胜感激!

2 个答案:

答案 0 :(得分:0)

您应该在任何函数之外声明#Model def shortTitle(self): return str(self.title)[:50] #modelAdmin class ItemAdmin(admin.ModelAdmin): list_display = ['shortTitle', ... Bitmap,然后简单地将它们回收用于循环内部(而不是在内存中创建BitmapData任何内容)

如果您确定不再需要来自new变量的位图数据,请仅在最后一张图片上使用.dispose()。否则,如果处置,您将不得不再次创建新的替代bm以供进一步使用。

var someThing :BitmapData = new BitmapData

答案 1 :(得分:0)

好的,我最终理解并解决了这个问题。

首先,我安装并运行了Adobe Scout。优秀的工具。

Adobe Scout memory profiling

你可能看不到(加上法语),我生成了3个与边缘对应的表面。右侧的“大”绿色条表示“大量内存消耗”,表示“位图显示对象”。有意思!从来没有听说过那些。

稍后进行Google搜索,我发现了这篇文章:https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e26.html

它解释了

  

例如,在前面显示的代码摘录中,一旦加载   pict Loader对象的操作完成后,pict对象将完成   有一个子显示对象,即位图,已加载。访问   这个位图显示对象,你可以写pict.getChildAt(0)。

所以我开始意识到,不知何故,Bitmap对象可能作为子项附加在myBigSprite的某些对象上。

最后,我创建了一个递归函数来搜索和销毁Bitmap操作后BitmapData中包含的所有ByteArraymyBigSpritedraw个对象

//inside render function
bm.draw(myBigSprite, mtx, null, null, null, true);
destroyDisplayObjects(myBigSprite);

...

private function destroyDisplayObjects(obj):void{
    if ("numChildren" in obj){
        for (var i:int = 0; i<obj.numChildren; i++)
        {
            destroyDisplayObjects(obj.getChildAt(i));
        }
    }
    else {
        if (flash.utils.getQualifiedClassName(obj) == "flash.display::Bitmap"){
            //trace ('FREE BITMAP');
            obj.bitmapData.dispose();
            obj.bitmapData = null;
            obj = null;
            return;
        }
        else if (flash.utils.getQualifiedClassName(obj) == "flash.display::BitmapData"){
            //trace ('FREE BITMAPDATA');
            obj.dispose();
            obj = null;
            return;
        }
        else if (flash.utils.getQualifiedClassName(obj) == "flash.display::ByteArray"){
            //trace ('FREE BYTEARRAY');
            obj.clear();
            obj = null;
            return;
        }

        return;
    }
}

Etvoilà,在绘制操作后内存被100%清除,不再泄漏:)