Posts in Category "performance"

An Update on HTTP Content Encoding in AIR Applications

In keeping with my recent HTTP theme, I want to provide an update on a change to HTTP content encoding supporting in AIR 2.0.3, which has just been released.

The HTTP protocol permits server and clients to agree on encoding a document for transfer. For text and XML documents, this can significantly reduce transfer time, as they typically compress well.

Prior to the AIR 2.0.3 update, AIR supported gzip and flate encodings only on Mac OS and Linux. On Mac OS, this was a result of using the default OS HTTP stack, which supports those encodings by default. On Linux, which has no default HTTP stack, we implemented direct support for these options.

On Windows, the capability was not available because AIR uses the OS HTTP stack, but Windows did not support these encodings prior to Vista. Therefore, AIR could not depend on this capability being present and did not enable it. Developers could work around this by managing the HTTP content encoding header themselves and performing the decompression in ActionScript, although that’s not a particularly fun option to implement.

As of the AIR 2.0.3 release, we’ve added support for gzip and flate encoding for all versions of Windows, thus bringing it to parity with Mac OS and Linux. This change applies to all applications using the 2.0 (and later) namespaces. Applications using the 2.0 namespace will automatically benefit from this change when run on the 2.0.3 and later runtime; there is no need to re-publish.

Object Graphs, the GC, and System.disposeXML()

AIR 1.5.2 contains a new, performance-related API that heavy users of XML may find handy, System.disposeXML(), that is an instructive example regarding use (and abuse) of the AIR garbage collector.

When an XML document is loaded, it’s stored in memory as a graph of individual objects representing elements, text, attributes, and so on. Each pair of related objects–for example, a parent/child element parent–are linked, in the underlying representation, with pointers going in both directions.

This is a convenient representation for traversal, but can be problematic for the garbage collector. As I mentioned in my earlier post about referencing counting and ActionScript objects, the garbage collector will eventually find and discard the entire set of objects after the last external reference is removed. However, it takes more work for the GC than less-connected data structures.

In practice, the amount of time it takes the garbage collector to do its job is related both to the number of allocated objects and the number of pointers between them. So while it is nice that the GC is capable of finding even these highly-connected graphs of objects, using them is also asking it do a lot of work. You can reduce this workload by explicitly disconnecting the pointers between objects.

For graphs of ActionScript objects, you can ease the GC workload by simply nulling out reference between the objects. Note that you don’t have to find every last reference for this to be helpful. The GC will still do it’s job in the end, and every bit of clearing references helps. For ActionScript objects this can be particularly helpful because, if their reference count then goes to zero, they can be cleaned up even before the GC sweep completes.

XML objects are a trickier case because the API doesn’t allow developers to traverse the actual object graph. That’s where System.disposeXML() comes in: It traverses the internal object graph backing the XML object, setting all of the internal points to null. Afterwords, the XML object is empty and, presumably, useless. But then, since you were done with it anyway, that shouldn’t be a problem.

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.

Performance-Tuning AIR Applications at the Adobe Developer Center

Interested in improving the performance of your AIR application? Have a look at Performance-Tuning AIR Applications, at the Adobe Developer Center. (This is a follow-up to my MAX 2008 presentation on the same subject.)

High Performance AIR Applications at MAX 2008

I’ll be at MAX 2008 this afternoon presenting a talk on High Performance AIR Applications. I’ll hang around for a bit afterward, too, for anyone interested in a more in-depth discussion.

I’ve posted the presentation and accompanying sample code on Acrobat.com.

If there are other performance-related topics you’d like me to address in this blog, please post a comment to that effect.