I am building HTML5 applications at Sencha. It is a great platform, take a look...

 

  Ted Patrick - Developer Relations @ Sencha


   Note: This is the personal blog of Ted Patrick. The opinions and statements voiced here are my own.



Memory Performance in the Land of References

DIGG IT!     Published Wednesday, July 15, 2009 at 9:46 AM .

Over the past few years I have seem my share of memory related issues in working with Flash Player and AIR. In every case, the issue always boils down to reference handling in that somehow code was written (typically innocently) that holds a reference to an object indefinitely. In all systems with a garbage collector memory system, you need to be very careful how you work with object instances. Lets look at the details:

var arrayRef:Array = new Array();

Here "arrayRef" is a reference holding a newly created Array object instance. Within the Flash/AIR VM, "arrayRef" is actually a reference to raw block of memory within the player. Whenever you want to do something with the array instance, you use the "arrayRef" reference to read/write/execute properties and methods of the object stored in memory.

The real fun begins when references are passed around within the system like so:

//direct reference
var arrayRef2:Array = arrayRef

//property reference
var objRef:Object = {};
objRef.foo = arrayRef;

//event reference via method closure
mylistener.addEventListener( "woot" , customMethodOnReference );

//In AS3 all methods have "closure" and thus hold a reference to the object instance. If you pass methods, you pass an object instance! Method closures are a handy feature but they have reference implications attached. Be careful!


The lesson here is that you can pass references very very very easily, maybe too easily, and thus unless you are tracking down all instance usage, you will see app memory accumulate. This is especially true with application data objects where lots of data flows into the player via the network and data is consumed by an application. Each object created via network operation must be carefully watched and managed.

In terms of memory consumption no object is more problematic than XML/E4X. In Flash Player XML and E4X are an object with a collection of inner objects. They are trees of objects all with internal references. When they are used, you need to be careful how you access them and reference the objects they contain. If you set values based on data within XML/E4X, you will hold the whole XML object in memory unless you release the objects. There are a few reports of "Memory Leaks" within E4X when using certain XML features (I AM WRITING ANOTHER POST ON E4X and LEAKS...STAY TUNED) and some of these are bugs but a large majority seem to be misuse of reference of result XML objects. How you use the references within an XML object is really important and developers need to be careful what they hold onto. I tend to create new Model objects from E4X data queries and never reference internal E4X objects directly in code. This has helped my projects as a practice.

Flash Player and AIR release memory when all object reference to an objects are gone (not counting internal reference). The garbage collection occurs incrementally so as not to slow down the player as it processes ActionScript and renders graphics. The garbage collector within AS3 works via deferred reference counting backed by incremental conservative mark/sweep collector. For detail on the VM and Garbage Collector, this PDF is the best guide I know of. When objects are created you will see memory consumption rise within the Flash Player (via flash.system.System.totalMemory) as new memory is allocated from the system to the runtime. Player and AIR maintain a buffer of available memory for newly created objects and if there is nothing to collect (recover memory) the player will get more memory from the system. This will show up in the Profiler as rising memory but you will never see this value fall (via flash.system.System.totalMemory). Once memory is acquired by the player for use, it remains used and is recycled using the garbage collector. The key here is that you need to lower instantaneous memory consumption within your application and be very careful to allow the player to garbage collect over time. Adding too many objects at once will force player to generate new objects and acquire system memory if the buffer isn't enough.

Long story short, you have full control of memory use within your applications through careful objects creation and reference management. The problem is it isn't automatic and you need to be careful with references.

Regarding E4X memory issues, I am planning to post this week on the issue.

Manage your references!

Cheers,

Ted :)


Where to find me:

Ted on Twitter - @__ted__
Ted on Adobe Groups
Ted on LinkedIn
Ted on Facebook
Ted at Adobe

Latest

Lists

Links

Jobs

city, state, zip

Archives