抄文如下:
首先看看AS的回收機制
Flash中的無用單元回收機制(Garbage Collection)用來自動清除記憶體中不再需要的變數,有兩種演算法執行:
引用計數 和 標識和清除.
引用計數用來追蹤記憶體中對象的所有引用,當我們建立一個指向這個對象的引用時,它的引用計數就進行增1操作.
var a:Object = new Object(); // new Object in memory given reference count of 1
var b:Object = a; // Object now has reference count of 2
當記憶體中不再存在任何指向這個對象的引用時,無用單元回收器(GC)會將這個對象從記憶體中清除掉.
delete a; // Object has reference count of 1
delete b; // Object has reference count of 0, removed from memory
要注意的是,delete 操作符只是用來刪除相關的變數,但是,它並不會將對象從記憶體中清除掉,那是無用單元回收器的工作,還有,delete 操作符不能刪除類成員變數.
引用計數在有些時候並不能正常工作.例如,如果你定義兩個對象,它們只是引用自身,而沒有任何別的對象引用它們,這樣它們的引用計數是大於0的,可以卻沒有辦法訪問到它們.
var a:Object = new Object(); // reference(a) count 1
var b:Object = new Object(); // reference(b) count 1
a.b = b; // reference(b) count 2
b.a = a; // reference(a) count 2
delete a; // reference(a) count 1
delete b; // reference(b) count 1
這裡對象a和對象b已經從當前範圍內刪除掉(delete)了,所以它們是沒有辦法訪問到的.但是,從對象a仍然是可以訪問對象b的,而且對象a也可以從對象b訪問到.對象a和對象b看起來已經被程式員手動刪除一樣,而實際上,它們還存在於記憶體中,而且它們的引用計數還大於0的,所以這種情況下引用計數有很大的缺陷,而標記-清除演算法可以解決.
標記-清除演算法是這樣一個過程,程式會在一個基礎的地區(比如root或舞台stage)掃描所有的對象和引用,標記出已經發現的,那些沒有發現的是不能被訪問到,或者已經被刪除(delete)掉的.還拿上面對象a和對象b的例子來說,因為對象a和對象b都不能被根目錄(root)下任何對象訪問到,它們不會被標記,最後會被無用單元回收器(GC)清理掉.
//掃描流程說明
[root] <- scan…
[objectRef (marked)] <- scan…
[objectRef (marked)] <- scan…
[objectRef (marked)] <- scan…
…
[delete all objects not marked]
標記-清除演算法相對於引用計數可能會花費較多的時間,也不會像後者那樣頻繁的執行.事實上,有時候它在影片中幾乎是不執行的,當標記清除執行時,時間軸已經經過了好多幀了,也就是說,有時候你覺得變數已經從記憶體中刪除掉了,而實際上它還會在記憶體中存在一段時間.對於那些與對象的指令碼,比如enterFrame事件,當對象實際刪除之前這些事件還在執行,所以你始終應該記得在不使用的時候清除(clearup)你的事件.
什麼是弱引用(Weak Reference)
如果你想使用一個不被GC計數的引用,可以定義一個弱引用.弱引用會被引用計數器忽略掉,即使引用的對象被刪除(delete)了,而弱引用還可以存在.
AS3.0中的弱引用是不能到處使用的,只能在以下兩個地方使用:一是用於Dictionary對象,Dictionary類的構造器使用一個可選擇的參數來決定Dictionary執行個體的索引值是否使用弱引用.預設情況下為false,使用的是強引用,如果設定為true,使用弱引用.
var dict:Dictionary = new Dictionary(true); // use weak references as keys
如果你做了上面的操作,那麼你用來存放資料的索引值不會被算做對象的引用,也就是對象引用計數不會增加.
var obj:Object = new Object();
dict[obj] = true;
delete obj; // obj can be garbage collected since the dict reference isnt counted
另外可以在EventDispatcher類的addEventListener方法指定弱引用,addEventListener方法有一個參數可以用來指定接聽程式引用為弱引用.
// addEventListener(type:String, listener:Function, useCapture:Boolean= false, priority:int = 0, useWeakReference:Boolean = false):void
addEventListener(MouseEvent.CLICK, clickHandler, false, 0 true); // use weak references
預設情況下這個參數也為false,使用強引用,這裡指定接聽程式引用為弱引用,從而調用無用單元回收器(GC)來回收無用接聽程式,是一個好的習慣.