24 Sep 2007, 4:34pm
Design Patterns Flex
by Dan Schultz


When to Use Weak References

Understanding when to use a weak references, versus strong references can be a confusing one. It took me awhile to fully grasp when, and when not to use one over the other. On top of that, there’s very little documentation on the LiveDocs about the subject. Under the documentation for IEventDispatcher.addEventListener(), it states:

useWeakReference:Boolean (default = false) — Determines whether the reference to the listener is strong or weak. A strong reference (the default) prevents your listener from being garbage-collected. A weak reference does not.

And here’s what they have listed for the Dictionary’s constructor:

weakKeys:Boolean (default = false) — Instructs the Dictionary object to use “weak” references on object keys. If the only reference to an object is in the specified Dictionary object, the key is eligible for garbage collection and is removed from the table when the object is collected.

Ok … thanks. So, I did some Googling, and both Ted Patrick and David Coletta have much better information on the subject.

The basic idea behind strong references and addEventListener is this: when you call addEventListener and you pass it the function that you want to be called when the event fires, the event dispatcher is actually grabbing and holding a reference to that class and function it contains. As we all know, an object won’t be garbage collected until every reference to it doesn’t exist anymore. This insures that the event dispatcher always has a reference to the function that needs to be called. However, if you’re not careful, this can be a breeding ground for nasty memory leaks.

So, here’s my short list of do’s and don’ts related to strong vs weak references and event listeners:

  • Always use a weak reference when adding an event listener to a class that’s a singleton, or any object that you expect to live throughout the life of your application. Remember, this applies to most of Flex’s manager classes, including the SystemManager, and any event dispatching classes that your singleton’s contain.
  • Always use weak references when adding Cairngorm commands. The event dispatcher in Cairngorm is a singleton, and will always keep references to those command classes.
  • According to Ted, weak references are 10x slower. (True when referring to member access, but not event listening.)
  • It’s safe to use strong references when you’re adding an event listener to itself (i.e. the instance dispatching the event).
  • You should use a weak reference when adding an event listener to the Timer class.
  • Lastly, always make sure to clean up and remove any event listeners your classes are using when they’re no longer needed. I follow .NET’s approach, and I have an interface called IDisposable. This interface contains a single method called dispose(), and inside I remove any event listeners that the class might be using. Additionally, you could clean-up any BitmapData objects you might be using, among other things. Most, if not all, of my classes that I write implement this interface, and I just make sure to call dispose() when I know the object is no longer needed.

If there’s anything else to look out for, I’d love to hear them. It’s always good to be proactive when it comes to memory leaks.

Ted’s post that you reference (and the speed advantages) are connected to strong typing (defining variable types and function return types), not strong references as they apply to event listeners. He does use the term(s) strong/weak reference a few times but they have different meaning in the context of his post. I could be wrong, but I am pretty sure there are no performance differences between strong and weak event listeners.

Thanks for the correction Ben. I see what Ted is referring to now.

There is some confusion over the terminology there. At one point it was suggested to call this weaker references as “weak reference” are in fact a feature of the language. The language lawyers hammered me on it. At essence here is how strong a reference is during garbage collection not the speed of member references. My article is really talking about how fast a reference can be accessed. In AS3/AVM2 if you use strong typing, the compiler maps a class to a Trait (a middle class object for mapping purposes) which results in member access that is equivalent to C++ member access speed. If you use weak typing, the result is member access is a hash table lookup and is thus highly dependent on the depth of the inheritance chain.

We do need better names for all this stuff, it gets confusing.

Great post,

Ted :)

That always happens if we use “weak reference” in “addEventListener”. That risk?

I am developing an application large and I have some problems with memory leak

This is very cool. As someone who is new to Flex, I am glad I learned this now and not later. Thank you!

14 Jul 2008, 8:03pm
by Anonymous


Hi Dan, you didn’t really spell out when not to use weak references. I got the impression that all listeners should be weak references reading this and still have no idea when not to use weak reference (or when strong reference is highly preferred over weak)

This stuff makes my head hurt, but your article helped organize the ideas for me. I had to step back and think about what I was doing when I add an event listener to an object.

Basically, if object B adds a listener to object A, the result is that A has a
reference to B. This means that B cannot be garbage collected, even if it is no
longer used.

Now, if B is otherwise a target for garbage collection, it is certainly no
longer interested in events from A.

So, it seems to me like the weak reference option is there to protect you from
not cleaning up. Instead of removing event listeners from B, you just
rely on the weak reference because you know that if object B is otherwise
a candidate for removal, it certainly isn’t interested in events anymore.

If my analysis is correct, the only time you need a strong reference to an
event listener is when you think that this single reference to your object
is the only thing keeping it from being kicked out. But how
often does that happen? If nobody has a reference to an object, that
object is doing nothing, so it won’t be missed.

Seems to me that weak references to event listeners should always
be safe. I’m not sure that removing listeners is necessary for memory
leak prevention.

Someone please correct me if I’m wrong.

@Anonymous, thanks for bringing this to my attention. I’m in the process of writing a post about references in general, encompassing strong, weak, soft, and phantom references.

@Larry, I think you got it :-). When B adds a listener to A, A is holding a reference to B. Because of this, B will not be garbage collected until A is removed from memory, or B removes its listener from A, or the only references to A are weak, which triggers A to be removed from memory.

Yes, you are right when you say that removing listeners is not necessary for memory leak prevention. As long as all the listeners you add to object A are weak.

Do you have an example of IDisposable? How or when do you call the Dispose() function? What if your component is nested and you only want to call it when the nested components parents,parent is removed from the stage?

@Jdog, when working with compositions of objects, such as display objects. I usually follow a principle of the parent always managing its children. In the example you provided, the parent would call dispose() on any objects that it contains. When the dispose() method is called on the children, the children would then call dispose() on any of its children, and so on.

For Mixbook.com, I have a Page class which manages an array of text and image items. When a user deletes an image item, the page component calls ImageItem.dispose(). Inside here, I clean up any listeners to the system manager, and explicitly dispose of the BitmapData that the item is using – which frees the memory of the bitmap immediately, instead of waiting till the next garbage sweep.

Another example of dispose(), is the LoadManager class that is used throughout Mixbook.com. This class essentially controls anything from preloading images, to loading stylesheets and fonts – where each type of loadable item has its own class. Based upon where the user is in the book, requests to load items are being either added or removed from the LoadManager class. When a load item is removed from the LoadManager, the LoadManager calls dispose() on the item, which cleans up any resources its using. Such as calling Loader.close().

So the dispose() method simply acts as an interface that the parent can use to say to its children, “Hey, I know the life of this object is finished, clean up any references/resources it’s using.”

you spelled BREEDING GROUND wrong

:>

Userful information though…thank you for posting!

Hi, just a great article!

I try to use the profile to find memory leaks and I adapted your idea with the IDisposable interface. In combination with the flex sprite monkey patch (http://dougmccune.com/blog/2008/02/21/monkey-patching-flexsprite-to-list-all-event-listeners-on-any-flex-component/) [use carfully!] most of the objects should be cleaned up from the garbage collector. Unfortunately I have objects left, i.e. a lot of list item renderes and other objects. When I check the back references I can see there are some references:
- mx.binding:FunctionReturnWatcher
- mx.binding:Binding
- mx.binding:PropertyWatcher
and so on. Do these back references prevent my object from being garbage collected?

@Russ, I prefer “breading grounds” .. lol. thank you for pointing that out.

@Mario, it depends. I’ve noticed that loitering objects that have a prime number of instances are usually a good indicator that the object is leaking memory.

30 Apr 2009, 2:56am
by elextra


Commenting on your first argument there:
“Always use a weak reference when adding an event listener to a class that’s a singleton….”

I agree that a weak ref is enough. But my question is , what if I used a strong ref, what could happen? (mem leaks?? should not be, since the
that singleton obj is bound to live throughout the life of the app, the listener will do too).

Thanks.

Not necessarily; remember, that the dispatcher always holds a reference to the listener. Because the singleton lives throughout the life of application, it will always hold reference to the listener object, if not cleaned up properly.

Take the example of the SystemManager in Flex. If you listen to a MouseEvent from a UIComponent that is dispatched by the SystemManager, and add the component to the stage. When you remove the UIComponent from the display list, that object will not be removed from memory, because the SystemManager is still holding reference to it through the listener object.

*name

*e-mail

web site

leave a comment