The reference to the key is weak, the reference to the value is strong. GC is opportunistic and thus you get the results you saw.
IOW, as soon as weakObj is on the RHS of the =, it is strongly referenced and won't get GC'd until the key has no more references. ________________________________ From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of iiley Sent: Monday, January 28, 2008 11:01 PM To: [email protected]; [EMAIL PROTECTED] Subject: [flexcoders] Dictionary weakKeys feature or it's a GC bug Hi list, I'v done some tests many days to understand how will Dictionary with weakKeys works, but i can't understand some situations. Here's my tested conclusion: (for below, weakObj is a object that are not referrenced by any where) A.These cases the weakObj will be garbage collected, memory will be free: 1. dictionary[weakObj] = a int, Number or a string, null, or new Object(). B.These cases the weakObj will never be garbage collected, memory will not be free: 2. dictionary[weakObj] = weakObj; 3. dictionay[a int, Number, or a string] = weakObj; C.These cases the weakObj will some be garbage collected, memory will be free a little: 4. dictionary[new Object()] = weakObj; 5. dictionay[anotherWeakObj] = weakObj; Well, that's my test result, i think it is very strange for B and C especially 4 and 5, here's my test class, if you don't believe, you can test it by yourself. I can't understand for 5, why they can't be GC? in my test about 10000 instances created, just 1000 be GCed in about 1000 seconds, in fact for 4 and 5, you can trust GC can works for you, because the memory will keep increasing, never drop. Here's my test class(change c.test4() call in __timer method to switch test case): (here's a picture of the profile for each test case: http://demo.aswing.org/dictionary.gif <http://demo.aswing.org/dictionary.gif> ) ________________ package { import flash.display.Sprite; import flash.events.TimerEvent; import flash.system.System; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.utils.Timer; public class TestDic extends Sprite{ private var testArr:Array = []; private var timer:Timer; private var textField:TextField; public function TestDic(){ textField = new TextField(); textField.autoSize = TextFieldAutoSize.LEFT; timer = new Timer(5000); timer.addEventListener(TimerEvent.TIMER, __timer, false, 0, true); timer.start(); addChild(textField); } private function __timer(e:TimerEvent):void{ var c:DicCase = new DicCase(); testArr.push(c); c.test4(); textField.appendText(timer.currentCount + " Memory : " + (System.totalMemory/1024/1024) + "M\n"); } } } import flash.utils.Dictionary; class DicCase extends Sprite{ private static const N:int = 100; private var dic:Dictionary; public function DicCase(){ dic = new Dictionary(true); } public function test1():void{ for(var i:int=0; i<N; i++){ dic[i] = new ComplexObj(); } } public function test2():void{ for(var i:int=0; i<N; i++){ dic[i+""] = new ComplexObj(); } } public function test3():void{ for(var i:int=0; i<N; i++){ dic[new Object()] = new ComplexObj(); } } public function test4():void{ for(var i:int=0; i<N; i++){ var obj:ComplexObj = new ComplexObj(); dic[obj] = obj; } } public function test5():void{ for(var i:int=0; i<N; i++){ var obj:ComplexObj = new ComplexObj(); dic[obj] = null; } } public function test6():void{ for(var i:int=0; i<N; i++){ var obj:ComplexObj = new ComplexObj(); var key:Object = new Object(); obj.key = key; dic[key] = obj; } } public function test7():void{ for(var i:int=0; i<N; i++){ var obj:ComplexObj = new ComplexObj(); dic[obj] = i; } } } import flash.display.Sprite; import flash.utils.Dictionary; class ComplexObj{ public var key:Object; private var eatMemory:Array; public function ComplexObj(){ eatMemory = []; for(var i:int=0; i<100; i++){ eatMemory.push(new Sprite()); } } } ________________ -- iiley AsWing http://www.aswing.org <http://www.aswing.org> Personal http://www.iiley.com <http://www.iiley.com>

