Weak References
Weak key support in the Dictionary class is one of those rarely-used features that can be greatly useful on occasion. This is the only place in the Flash API where weak references are used. In Java, there is another useful class for when you just want to make one weak reference, not a whole table of them: the aptly-named WeakReference class. Below is my own implementation, which is both simple and useful.
My implementation wraps the weak key support that dictionaries support with a class that provides convenience access to the singular value it stores. Since you can put anything in a Dictionary, this class will allow you to store anything. For more type safety, you may consider deriving from this class and providing a getter that casts the referent to the appropriate type and does type checking in the constructor. Unfortunately, there’s no good way to add speed to this, so use it only where the benefits of a weak reference outweigh performance concerns. Here is the WeakReference class I have implemented:
package { import flash.utils.*; /** * A weak reference to an object inspired by Java's WeakReference class: * http://java.sun.com/javase/6/docs/api/java/lang/ref/WeakReference.html * This class holds an object, but if that object is ever not referenced by * anyone but the WeakReference, it is garbage collected and no longer * retrievable. * @author Jackson Dunstan ([email protected]) */ public class WeakReference { /** Dictionary that holds the object */ private var __dictionary:Dictionary; /** * Make a weak reference to an object * @param referent Object this weak reference should refer to */ public function WeakReference(referent:*) { // Use weak key support __dictionary = new Dictionary(true); // Use the object as the key so it is weak. Use a dummy value since // we do not care about it. __dictionary[referent] = true; } /** * Get the object this weak reference refers to * @return The object this weak reference refers to or undefined if the * object was garbage collected because no other objects other * than the weak referene refered to it. */ public function get referent(): * { // We don't have a strong reference to the referent so we have to // search for it. Luckily we know that there is only zero or one // iterations possible since we only store one item in the // dictionary: the referent. for (var referent:* in __dictionary) { return referent; } return undefined; } } }
As you can see, it is mostly comments explaining rather simple functionality. Here is a simple example app for you to try out:
package { import flash.ui.*; import flash.text.*; import flash.events.*; import flash.display.*; public class WeakReferenceTest extends Sprite { private var __statusDisplay:TextField; private var __reference:WeakReference; private var __referent:*; public function WeakReferenceTest() { __statusDisplay = new TextField(); __statusDisplay.autoSize = TextFieldAutoSize.LEFT; addChild(__statusDisplay); __referent = new BitmapData(512, 512, true); // ~1MB __reference = new WeakReference(__referent); addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); } private function onEnterFrame(ev:Event): void { __statusDisplay.text = __referent ? "Still holding strong reference to referent\n" + "Weak reference has: " + __reference.referent + ".\n" + "Press SPACE to release referent." : "Released strong reference to referent.\n" + "Weak reference has: " + __reference.referent; } private function onKeyDown(ev:KeyboardEvent): void { if (ev.keyCode == Keyboard.SPACE) { __referent = null; } } } }
Usage of the app is simple. Notice that the reference holds the referent (BitmapData) until you press the SPACE key. Without notifying the WeakReference, the referent is dropped when it is collected by the garbage collector. This is weak references in action!
I recommend adding the WeakReference class to your projects and keeping it in the back of your mind. You may find a circumstance where it helps you out. If you never use it, it will never be included in your SWF and cause you no harm. Besides, it’s free. Enjoy!
#1 by Sev on September 30th, 2009 ·
The only thing to be aware of when dealing with weak references within Flash is that the object still “lives” while in memory, even when its marked for GC. This usually is no big deal (GC will clean when it thinks it’s time to do so), except for weak listeners. So these dead objects would still receive events – something that gave me a headache recently. On a side note: it’s pretty funny to see you write the exactly same class I’ve written 1w ago only (well, apart from the naming of course). I’d love to see weak references built into the language by the way… there’s just too much potential for memory leaks anywhere.
#2 by jackson on September 30th, 2009 ·
Thanks for pointing this out. I’ve also heard that weak dictionaries don’t do well when the keys are Functions. I agree about the memory leak issues. It would sure be nice to have more control over the GC, a native weak reference class, and fewer bugs in the existing weak reference support.
#3 by aginguinoks on April 1st, 2011 ·
Please help me to beget bank
#4 by TedgeBizNeN on June 21st, 2011 ·
Hello all! I like this forum, i set up tons gripping people on this forum.!!!
Pronounced Community, consideration all!