April 29, 2008

AIR/Flex: Memory optimisation

Moving to doing some optimisation within my AIR application now, using the Flex 3 Profiler. I was noticing some interesting results, primarily that removing redundant event listeners and display children doesn’t always result in memory being freed up back to the system. Not as bad as a memory leak, but not quite what I wanted. As a result I’ve just been reading up a bit on optimising memory and garbage collection in Flex/AIR. From what I can see, although garbage collection in AS3 is actually quite good, there are a few tips, tricks and caveats…

Weak-referencing
It’s possible to help garbage collection along a little by using weak references on events listeners:


myObject.addEventListener("eventName", handlerFunction, false, 0, true);
The last parameter being the weak reference flag. This saves having to manually remove the listener and means objects will be automatically removed by the garbage collector, but it can make debugging problems difficult because the collector won’t necessarily remove the object on its next pass. A solution to this is to force the collector to sweep and remove de-referenced objects.

Manual garbage collection
Sean Christmann (eBay Desktop) demonstrates a method whereby it’s possible to manually force the garbage collector to sweep and remove memory objects using

flash.system.System.gc();
flash.system.System.gc();
(yes you need to call it twice, once to flag objects, once to remove them). As Sean describes though, using weakly-referenced objects can make it harder to track problems:

Trust me when I say that its a lot easier to debug an application with memory leaks due to strong listeners, then it is to debug an app in which users report random failures because underneath the hood weakly referenced objects are getting accidentally destroyed when the GC kicks in.

Flash Player
Flash Player’s garbage collector may sometimes ‘swap out’ dereferenced-but-not-yet-destroyed objects for new ones under its normal garbage collection process, that is it will maintain a certain memory ceiling and not go above it, but some object types are harder to destroy than others because they get referenced into the player – these are generally the types of object that work asynchronously, Loaders being one example; see Flash’s Dirty Secret, and Timers are another. Memory paging can also get quite fragmented because Flash was never optimised for the kinds of application where it might be running for hours, days or even weeks as an AIR application in the System Tray.

AIR Windowing
I’d not really considered this before moving to AIR, but the windowing capabilities mean that managing objects and garbage collection across multiple windows should be handled with care, because it’s possible to lose the ability to reference objects when application windows can be closed, or the application is running in the Tray and therefore has no focus. Sean describes another caveat where any EnterFrame handlers (which you might be using to control the collector) must be re-referenced across multiple windows.

The Elastic Racetrack
Finally, although this isn’t a memory thing, a word about execution time in Flex/AIR; each ‘frame’ of execution in your application is tied to the elastic racetrack concept. Flex has to balance the load between AS code execution, rendering and event broadcast/handling around a single continuous loop of execution, with allocation within each cycle dependent on the load for each. The depth of the display tree, or the execution time of a method will affect what gets done when during a particular frame or ‘lap’.


- 4 comments by 2 or more people Not publicly viewable

  1. Chris May

    I don’t know how Flash’s GCs compare to Java’s, but it’s generally received wisdom in Java-land that manually calling the garbage collector within your app is a terrible idea. Not only do you induce pauses in your app (even the server-side throughput collector includes some stop-every-thread processing, and the client-side collectors are much worse) and CPU spikes (GC on a large heap is expensive both in CPU and memory IO terms), but you also prevent the garbage collector from making intelligent decisions about how to size the generations within the heap, thus making things worse in the long run.

    Manually dereferencing objects once they’re not required is a much better bet than using weak references and keeping your fingers crossed for a garbage collection; That quote of Sean’s is right on the money, IME.

    29 Apr 2008, 20:41

  2. Steven Carpenter

    Thanks Chris – up to this point that’s exactly what I’d done – it’s much better IMO to manually remove listeners once they are no longer needed and while it’s easy to think a few event listeners won’t make much difference, in a typical application there could be quite a few and they all quickly up. I’m not doing enough display object optimisation I think though, so I’m going to see whether I can remove display objects more effectively next.

    29 Apr 2008, 23:41

  3. arpit

    From the Flex docs for garbage collector:
    For the Flash Player debugger version and AIR applications only.
    http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/System.html

    I am not sure calls to gc() work in non debug players

    30 Apr 2008, 02:27

  4. Steven Carpenter

    Cool – thanks for the links and info. It’s interesting that a gc() call wouldn’t work in the a non-debug player, makes sense I guess.

    30 Apr 2008, 09:06


Add a comment

You are not allowed to comment on this entry as it has restricted commenting permissions.

Search:

MXNA link

Tweets



    Tags

    Other blogs I like...

    Black Pepper Software

    Eismann-sf Go to 'Comments on: Design News for Web, Graphic Designers'

    Ted On Flex Go to 'Ted On Flash'

    Galleries

    Meetups:

    Not signed in
    Sign in

    Powered by BlogBuilder
    © MMXXI