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…
It’s possible to help garbage collection along a little by using weak references on events listeners:
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.
myObject.addEventListener("eventName", handlerFunction, false, 0, true);
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
(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’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.
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’.