Skip to content

Drawing API Memory-Leak in Flash 10.1

by pixelpracht on Juli 6th, 2010

When trying Rune Hunt in the new 10.1 version of the Flash Player I noticed a HUGE performance drop. In the old player it would take about 27ms on my system (debug build) to update the game’s state and render the next frame. In Flash Player 10.1 this changed: The time it took to calculate a frame started fluctuating and increased to 48ms on average.

A member of the Flash Player Engineering team replied to my inquiry about known performance issues:

General actionscript performance is not any slower in 10.1 than 10.0 from our testing, it must be something particular in your code which exhibits the problem. Do you have a reproducable test code or a url you can point us at?

So I tried to isolate and reproduce my problems. It seems that my problems are caused by a Memory Leak in the Drawing API. I wrote a simple test application to illustrate the issue and hopefully find a work-around.

//... there`s a buffer as rendertarget and a flare
private var _flare:BitmapData = null;
private var _buffer:BitmapData = null;

//each frame I render the flare 100 times into the buffer
for(var i:int = 0; i < 100; i++)
    _buffer.draw(_flare, null, null, BlendMode.ADD);

In the 10.0 player there is no memory fluctuation caused by this code. But in the 10.1 player each draw-call allocates new memory. The total memory is increasing linearily until the garbage collector kicks in. This of course effects the performance.

In all browsers and on all systems that I tested the memory leak was present in the new player – but the way the garbage collector handled it varied so the graph isn’t always as clear. You can test it for yourself. And here’s the source for the test application.

My guess at what happens: BitmapData.draw() method accepts IBitmapDrawable an interface that is implemented by all DisplayObjects and BitmapData objects. If you pass a BitmapData object however it seems like memory gets allocated based on the size of the render target. This memory is not reused or instantly freed but has to be collected by the garbage collector.

Knowing this there’s a neat workaround: If you wrap the BitmapData in a Bitmap before you draw it you can avoid the bugged code and the memory keeps steady!

//wrap _flare in a Bitmap (do this only once!)
_flareBmp = new Bitmap(_flare);

//now instead of _flare render _flareBmp
for(var i:int = 0; i &lt; 100; i++)
 _buffer.draw(_flareBmp, null, null, BlendMode.ADD);

From → Tutorials

11 Comments
  1. Thanks for this workaround!
    I hope flixel game engine now stop lose fps…

  2. I can’t believe I had to look so hard to find a post on the internet about this. The closest thing I could find was in regards to flash player 8. I am finishing up a game that uses bitmap data for hit testing. The memory would consistently climb to 65mb before dropping back down to 30mb. Gave this a try and it completely fixed the issue. Thanks!

    I did a simple test as well here http://www.ciryusnights.com/flashStuff/BmpdDrawMemoryLeak.html
    I put a link back here as well if you don’t mind.

    • Nice work.

      Does the work around apply if you use the Bitmapdata lock and unlock functions before and after the loop?

      • Whether you lock/unlock your target bitmap or not makes no difference. The bug occurs in both cases and the fix works in both cases.

        In the sample I provided it doesn’t even affect the performance. Locking meant to be used (only) if you’re going to manipulate the image using multiple calls to setPixel or setPixel32.

  3. Nice site Thomas!

    Keep up the good work! :)

  4. ForrestUV permalink

    I’m drawing a bitmapdata already wrapped inside a bitmap but it doesn’t work for me :(

    Any other tip?

    • What exactly does not work? Technically both a wrapped and an unwrapped BitmapData should give the same results except that the latter is putting more load on the garbage collector.

      • ForrestUV permalink

        Wrapping or not the bitmapdata inside a bitmap makes no difference in my case.
        Memory grows every draw call :(
        I’m using Air2.5 btw…does it matter?

  5. ForrestUV permalink

    Ah.. I didn’t notice that the bitmap must be drawn instead of bitmapdata :)
    The workaround works…

  6. ForrestUV permalink

    10.2 is out and this bug isn’t fixed yet…
    nice Adobe…

  7. ForrestUV permalink

    ops
    It is just not fixed inside Air2.5 apps..

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS