ActionScript Objects are Reference-Counted

One of the most under-appreciated aspects of ActionScript memory management is that ActionScript objects are not just garbage collected; they are also reference counted. When their reference count hits zero, they are immediately freed. This happen irrespective of the state of the garbage collector.

For example, suppose you were to monitor memory use as you stepped through the following lines of code:

var buffer:ByteArray = new ByteArray();
buffer.length = 100 * 1024 * 1024;
buffer = null;

This code creates a 100 MB buffer, then discards the reference to it. After the second line executes, you’ll see memory use grow by 100 MB. (Using such a large number is convenient because it makes the results really obvious in your monitoring tool.) After the third line, however, you’ll see memory use drop back down immediately.

(Caveat: Monitoring memory use can be tricky in its own right, and you need to make sure you’re monitoring the correct measurements to see this effect. See Performance Tuning AIR Applications for more about how to monitor memory use.)

Despite this quick-cleanup capability, it often seems like the memory use of a given application tends to creep up over time. There are two major reasons for this.

First, it’s quite common in ActionScript programming that objects are connected—that is, have references to each other—in cycles. When a graph of objects contains a cycle it prevents the reference counts from going to zero even if the entire graph is itself unreferenced. The garbage collector will ultimately sort out the situation and free these objects, but it can take a while, and in the meantime the memory remains in use.

The second possibility is that there’s a “leak”, which is to say there’s an unintended reference to an object that is, at least logically, no longer in use. These objects simply can’t be freed: they have a non-zero reference count and, because they are referenced, won’t be collected, either.

You can combat the first issue (cycles) and help uncover instances of the second (leaks) by eliminating cycles in object graphs when discarding references to them. More about this in upcoming posts.