Memory/reference leakage in flash player
下面的例子示範了在 AS3 編程時,一不小心就會造成 memory leak。
-
private var p:Person;
-
private var arr:Array = [];
-
-
private function init():void{
-
p = new Person();
-
p.theName = "fooooooooooooooobarrrrrrrrrrr";
-
this.theText.text = p.theName;
-
//
-
arr.push( p );
-
//
-
this.theList.dataProvider = arr;
-
}
-
-
private function doClear():void{
-
p = null;
-
arr = null;
-
//this.theList.dataProvider = null;
-
trace("p: ", p);
-
}
主要的原因是:
1、FP9 的 Grabage Collection 是採用 reference counting,當一個物件生成後只要有被其它物件 reference 一次,它的 reference count 就會 +1,也就是說在下次 gc 發生時它不會被 mark and sweep。
2、以上面的例子,當一個 person instance 建立後,它被放進 arr,然後 arr 被指派為 List 的 dataProvider,這樣它就有兩個 reference counts了。
3、當執行 doClear()時,雖然將 p 設為 null,同時也清空了 arr的內容,但很不幸的,person instance 仍然存在。
4、原因是當 arr 被設為 List.dataProvider 時,在 List 內部就產生了一個 reference,這個可以從 debugging > variable 看出來,實際上在 List 裏面是產生了兩個 reference了,分別放在 source 與 list 這兩個變數裏。

這件事情的嚴重性在於,當程式執行階段要處理的 value object 非常多時,時間一久,memory leakage 就會無限擴大,而且最糟糕的是 gc 也幫不上任何忙,因此它會認為 person 還有被用到本來就不可以被清掉。
所以該怎麼辦呢?
很簡單,從現在開始起,AS3 developer 也要像 c/c++/java developer 一樣,個已負起記憶體管理的責任,心裏要清楚知道每個物件目前身處何方?它的 reference 數量?以及那些操作可能會造成reference leak?接者就是在物件不需被用到時勤快的將它們清掉。
在未來,Adobe 會推出 profiler 等工具讓 developer 可以比較輕鬆的觀察物件的生命狀態與記憶體配置,就會比較容易找出 leakage,但在那之前(預估還要半年),大家就靠自已吧...

