垃圾回收演算法主要依賴於引用的概念。
回收思路
- 區域性變數:區域性變數只在函式執行的過程中存在。這種情況只要在函式執行結束就可以判斷區域性變數沒有存在的必要了,然後回收其記憶體。
- 其他變數:主要通過跟蹤變數,對不再有用的變數打上標記。實現上的不同主要是標記無用標量的策略不同。
標記清除(常用)
思路
”物件是否不再需要“ => ”物件是否可以獲得“
垃圾回收器將定期從根(全域性變數)開始,找所有從根開始引用的物件,然後找這些物件引用的物件……從根開始,垃圾回收器將找到所有可以獲得的物件和收集所有不能獲得的物件。
垃圾收集器在執行的時候會給儲存在記憶體中的所有變數都加上標記。然後,它會去掉環境中的變數以及被環境中的變數引用的變數的標記。之後還有標記的變數被視為準備刪除的變數,原因是環境中的變數已經無法訪問到這些變數了。
引用計數垃圾收集
思路
“物件是否不再需要” => “物件有沒有其他物件引用到它” => ”物件是否可以訪問到“
如果沒有引用指向該物件(零引用),物件將被垃圾回收機制回收。
方式
跟蹤記錄每個值被引用的次數。如果這個值的引用次數變為 0,說明已經沒有辦法訪問到該值。
問題
對於迴圈引用的情況,由於兩個變數都至少引用一次,所以在這種策略下永遠不會被回收。
對於標記清除就不存在這種問題。函式呼叫返回之後,兩個迴圈引用的物件從全域性物件出發無法獲取。因此,他們將會被垃圾回收器回收。
參考
-
《JavaScript 高階程式設計》