概念:找出那些不再繼續使用的變量,然后釋放其占用的內存。他會按照固定的時間間隔,或代碼執行中預定的收集時間,周期性的執行這一操作。
標記清除
- 最常用的
當變量進入環境(例如在函數中聲明一個變量)時,就將這個變量標記為進入環境。從邏輯上講,永遠不能釋放進入環境的變量所占用的內存,可以使用任何方式來標記變量
垃圾收集器在運行時給存儲在內存中的所有變量都加上標記。然后去掉環境中的變量以及被環境中變量引用的變量的標記。在此之后,再被加上標記的變量將被視為準備刪除的變量,原因是環境中的變量已經無法訪問到這些變量了。最后垃圾收集器完成內存收集工作。銷毀那些帶標記的值,并回收他們所占用的內存。
引用計數
跟蹤記錄每個值被引用的次數。當聲明了一個變量并將一個引用類型值賦給該變量時,這個值的引用次數就是1.如果同一個值又被賦給另一個變量,則該值的引用次數加1.相反,如果包含對這個值引用的變量又取得了另外一個值,則這個值引用次數減1.當這個值得引用次數變為0時,說明沒辦法再訪問這個值了,就將其占用的內存空間回收回來。當垃圾收集器再次運行時,釋放那些引用次數為零的值所占用的內存。
限制:循環引用 => 指對象A中包含一個指向對象B的指針,而對象B中也包含了一個指向對象A的引用。
function problem () {
var objA = new Object();
var objB = new Object();
objA.otherObj = objB;
objB.anotherObj = objA;
}
上面例子中,兩個對象的引用次數都是2,。若是標記清除,由于函數執行后,兩個對象都離開了作用域,因此這樣合理。但在計數策略實現中,他們的引用次數永遠不會是0.加入這個函數被多次調用,會導致大量內存得不到回收。
解決:在不適用他們時,手動斷開引用。
= null;賦值為null.
在IE中
window.CollectGarbage();
會立即執行立即回收機制。
opera中,
window.opera.collect();