Flex/AIR Memory Profiling

15 05 2008

I’m entering the final stages of testing of my most recent Flex app and decided to start profiling this week. Everything I have since read on it suggests: Profile early, Profile often.

Oops.

Well, apart from spending almost two days pondering memory usage graphs (my major problem were significant memory leaks), I managed to get there and fix my major memory issues.

As it turns out, my major issues came from strong event listeners between static classes (my Remote Object services) and my modules. Garbage collecting modules is like components, you still have to ensure no other living parts of your application reference anything you’ve destroyed.

Stupidly, I spent a fair deal of time focusing on components that were added by my modules and were taking the most memory, instead of concentrating why the module itself was still residing in memory after i’d destroyed it. (The memory graph was nasty, lemme tell you).

One thing that I discovered after all that pondering, is that I would hope Adobe could clear up which references are strong and which aren’t. Looking through tens to hundreds of references

I am curious in the Silverlight vs Flex debate how well MS’s solution handles memory leaks and what options are available for profiling. I’m also interested to see how Adobe improves the Flash player now that they’ve created such a better model for developing Flash content: developers working in Flex/AIR, with the designers in Flash.





Flex/AIR, event listeners, weak references and memory leaks

12 05 2008

I’ve just been reading a book on Flex and came across a great point in the memory management department. That I think everyone should be aware of.

The book is Adobe® Flex™ 3: Training from the Source.

The great point is on memory leaks with event listeners.

Essentially, by creating a generic event listener on some object causes it to continually be referenced even when it is no longer used and therefore the memory is not reused by the Flash Garbage Collector.

Of course you can use the removeEventListener() method, but the point here was that you could also use weak references. Weak references are those that do not cause the GarbageCollector to bypass the memory. Essentially, without a strong reference to an object, the Garbage Collector can reuse that portion of memory next time you request some in Flex by instancing a new object.

You use weak references by calling addEventListener() with extra arguments. For example, if you wanted to handle the Complete event with a weak reference, you’d use:

addEventListener(Event.COMPLETE, onComplete, false, 0, true)

Just use the default values for the 3rd and 4th parameters – useCapture and priority – but use true for weakReferences.

Reading David Coletta’s blog, a very important note is NOT to add a weak reference to an anonymous listener.

Eg. the following code will not work as the anonymous function will be removed because it doesn’t have a strong reference and will go out of scope.

someObj.addEventListener(Event.COMPLETE, function(evt:Event):void{ Alert.show('Complete');}, false, 0, true); //doesn't work!

Another great point is that, in general, member variables do not require attached listeners to be weakly referenced.

This means you don’t have to go out and remove all of those click events on your Buttons declared in MXML, replacing them with ActionScript addEventListener calls because if the listener lives inside the same class, then they both die together.

In other words, if you’re application or component has a child that attaches a listener declared in the same class, then the strong reference won’t inhibit Garbage Collection if that containing instance is removed.

For example: Say I have some component I call MyControl.mxml

<mx:VBox>

<mx:Script>

<![CDATA[

private function doThis(evt:Event):void

{

//…

}

]]>

</mx:Script>

<mx:Button click=”doThis(event)” />

</mx:VBox>

Then I use it in my application thusly: (Application.mxml)

<mx:Application creationComplete=”onCrtComplete(event)”>

<mx:Script>

<![CDATA[

import com.justinjmoses.examples.weakreferencing.MyControl;

private var myCtrl:MyControl;

private function onCrtComplete(evt:Event):void

{

myCtrl = MyControl(this.addChild(new MyControl()));

}

private function removeIt():void

{

this.removeChild(myCtrl);

//now the entire control is available for Garbage Collection

}

]]>

</mx:Script>

</mx:Application> >

Now, when removeIt() is called, the component, MyControl, along with the Button and the listener inside, have their references removed, and are candidates for Garbage Collection.








Follow

Get every new post delivered to your Inbox.