I hope that I have covered the most important language feature topics in these last posts:
- 0.2 + 0.1 = 0.30000000000000004
- Classes, Inheritance, Interfaces, Packages, and Namespaces
- Const, Types, For/Each, and E4X
- Getting “this” right
- Static Initializers
- Do Arrays and Objects have side effects?
At this point we should be ready to move on and shift our focus towards the runtime features bucket. As we are doing so we first stumble over a group of odd features that seem to be right in the middle between language features and runtime features. Those are Weak References, Proxy, and Dictionary.
The Weak and the Strong
Before ActionScript 3 only Strong References existed: When your code used an Object the virtual machine also increased a reference counter associated with that Object. When an Object was not needed anymore the virtual machine would detect that and decrease the reference counter. Periodically the virtual machine’s Garbage Collector would destroy all objects whose reference counter was 0, which indicated that an Object was not any longer in use. With Weak References you can now also reference Objects without increasing their reference counter, which would allow the Garbage Collector to release more memory. There is a flip side to this feature, because weakly referenced Objects might get disposed by the Garbage Collector and your members and variables may become null at any time. You can never assume that a weakly referenced Object is still alive (unless you hold a separate strong reference to that Object of course, which would defeat the purpose).
flash.events.EventDispatcher: public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
If you no longer need an event listener, remove it by calling removeEventListener(), or memory problems could result. Event listeners are not automatically removed from memory because the garbage collector does not remove the listener as long as the dispatching object exists (unless the useWeakReference parameter is set to true).flash.utils.Dictionary: public function Dictionary(weakKeys:Boolean = 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. Note that the Dictionary never removes weak String keys from the table. Specifically in the case of String keys, the weak reference will never get removed from the key table, and the Dictionary will keep holding a strong reference to the respective values.
Here is what we could do:
- The runtime code could throw an error when useWeakReference or weakKeys are set to true.
- The runtime code could set that all weakly referenced Objects always to null as if they had been immediately disposed.
- The runtime code treats weak references always as strong references.
All three proposals have their pros and cons. In my opinion #2 is the worst solution, because it would break a lot of pre-existing ActionScript code. Technically, client code must not assume that weakly referenced Objects are always available. But in reality nobody expects the Garbage Collector to be that quick. Solution #1 is perhaps the cleanest solution but is also an annoying one, because it forces changes in the client code. The last solution is just cheating and may cause serious memory problems at runtime.
How about this solution?
4. Combine #1 and #3 using Dart Rules: Throw an error at runtime when useWeakReference or weakKeys are set to true in debug (“checked”) mode. Don’t throw an error in release (“production”) mode but instead treat weak references always as strong references.
That might be the way to go.