Object/Dictionary Reference counting and Memory Management
Since it is such an important topic and such a problem for the community, I thought I would make another post pertaining to optimizing for the garbage collector.
I was looking for information in the object/dictionary docs completely unrelated to memory management, but ran across this statement:
As long as any reference to the object exists, the garbage collection system will not recover the memory that the object occupies. If the value of myObject is changed such that it points to a different object or is set to the value null, the memory occupied by the original object becomes eligible for garbage collection, but only if there are no other references to the original object.
Wow.
Yes, you do need to explicitly set all non-simple types to null and splice/delete array indices and hash key entries.
Interestingly, one of the examples for doing just that is incorrect:
myObject = null;
delete myMap[myObject];
The two lines need to be reversed. Nulling out myObject before deleting it from the dictionary will not clear the dictionary’s reference to myObject. In other words, delete myMap[myObject]; when myObject is null equates to the line being executed as delete myMap[null];
Here is a quick working example:
package { import flash.utils.Dictionary; public class SampleClass implements IDisposable { private var _dictionary:Dictionary; private var _obj:Object; public function SampleClass() { _dictionary = new Dictionary(); _obj = {}; for ( var i:int = 0; i < 10; i++ ) { var sampleDto:SampleDto = new SampleDto(); _dictionary[sampleDto] = i.toString(); _obj[i.toString()] = sampleDto; } } public function dispose():void { for each ( var hash:* in [_dictionary, _obj] ) { //You can't explicitly cast to a data type using the for.. in loop //without a compile error on the dictionary, but since we //are looping through the dictionary and object hash together //the "*" is even more appropriate since the object and dictionary //hash by different types in this case. for ( var key:* in hash ) { var disposable:IDisposable = hash[key] as IDisposable; if ( disposable != null ) { disposable.dispose(); } delete hash[key]; } } } } } internal class SampleDto implements IDisposable { public var blah:Object = {}; public function SampleDto() { } public function dispose():void { blah = null; } }