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.

Advertisements

Actions

Information

6 responses

15 05 2008
Flex/AIR Memory Profiling « Justin J. Moses : Blog

[…] 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 […]

9 10 2008
ivan alvarez

Hi Justin,

In wich chapter of the book is explained the concepts you are talking about?

10 10 2008
Justin J. Moses

Ivan,

It’s from the last chapter: Lesson 26 “Profiling Flex Applications”.

Justin

5 03 2009
Ahmad

Hi,

Nice Article and thanks for sharing.
I got a little confused after reading the example in which you said there is no need to use weak references since those will be removed when the object is removed. I am not sure now in which case we need to use the weak reference, can you place an example for that as well. Thanks in advance 🙂

Ahmad

6 03 2009
Justin J. Moses

Ahmad,

Essentially, ALWAYS use weak references to prevent memory leaks. The only time you shouldn’t use them is when you use an anonymous listener. That is, when you don’t provide a name for the listener function but rather write it in the code:

someObj.addEventListener( Event.COMPLETE, function(evt:Event):void{ Alert.show(‘Complete’);} ); //Dont’ use a weak reference here because the listener function is anonymous

justin

3 11 2009
Robert

Normally if you add a listener to yourself, or to a child, you are ok. The memory leak problem is when adding a listener to a parent.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: