There are two basic ways to handle memory allocation. The first (used by C,C++) is to make the developer deal with it – you are responsible for allocating memory required and freeing it when you’re done. This allows the developer the freedom to decide when time consuming memory operations are done but the responsibility to keep track of everything or run into memory leaks (when unused memory isn’t released) or null pointer issues and the like when it’s released too soon.
The alternative chosen by Flash (and Java) is to use the runtime for garbage collection – i.e. let it decide how to allocate and free memory. The downside to this is that garbage collection can be time consuming and it’s nondeterministic – the runtime decides when it’s going to happen, not the developer.
There are several different algorithms for garbage collection. The Flash player uses a version comprised of “reference counting” and “mark-and-sweep”. (For a discussion of various garbage collection strategies see this article).
For reference counting, the runtime keeps track of all the active references to an object. Each object keeps a reference internally to its children and each child has a reference to its parent. There are also references created explicitly by the developer as a way to access the object in question. If the reference count is zero, nothing can access that object any more so it can be removed and it’s memory reclaimed.
The second phase, mark-and-sweep is more costly and required to discover circular references – i.e. objects that reference each other but have no outside references. To perform the mark, the player starts at the root of the application and traverses through its references marking each as it goes. When it’s reached the leaf nodes of all those references, any objects not marked can be “swept” away and deallocated. Due to its cost, this operation is performed iteratively over several frames and is only run occasionally.
What does all this mean to a Flash/Flex developer? Well you should be sure to remove all references to an object when you no longer need it. Often this will be done for you with variables going out of scope etc but you should be proactive in removing longer lived references you no longer require.
Event Listener Leaks
Objects that want to be informed of an event can register as a listener using the addEventListener() method. This results in the creation of a reference to the object doing the listening. Therefore if an object is listening for events, it may not be available for garbage collection.
There is a method called removeEventListener() that can be called to remove the reference when it’s no longer required which would allow the listener object to be removed when it has no other references. Unfortunately, it’s not always easy to know when to call this.
An alternative when calling addEventListener() optional parameters may be added, the last of which is a Boolean indicating a weak reference (the default is false). What this means is that if set true, the reference created for the listener is considered weak and not counted as a reference for garbage collection. A listener with only weak references remaining would be eligible for garbage collection. Here’s a post with more on weak references and here’s an opinion on when they shouldn’t be used.
Flash/Flex Performance tuning
FlexBuilder (and now FlashBuilder) professional comes with a profiler tool that allows you to investigate the memory usage of your application and time operations to look for areas in need of tuning.
There are no free alternatives that I’m aware of but you can use
flash.utils.getTimer() to time operations and
System.totalMemory to keep track of memory use in your application. Grant Skinner also has a performance test harness you might find useful.
A great resource with lots of links to more detailed information on memory management and performance is this page on Jun Heider’s blog.