詳細解釋 JavaScript 中的 Mark and Sweep 演算法?
Mark and Sweep 演算法
Mark and Sweep 演算法尋找的是“不可達”的物件,而不是“不再需要”的物件。該演算法是對引用計數演算法的改進。
該演算法實際上包含三個重要步驟。
- 根:一般來說,根是程式碼中使用的全域性變數。JavaScript 中的視窗物件可以充當根。該演算法使用全域性物件根來查詢物件是可達的還是不可達的。
- 然後,該演算法監控每個根及其子物件。監控過程中,根據提供的條件,一些可達的物件會被標記,而其餘不可達的物件則不會被標記。
- 未標記的物件,即不可達的物件將被垃圾收集。
標記階段
在標記階段,我們可以找到哪些元素被標記,哪些元素未被標記。假設我們將屬性“hello”賦值給物件“obj1”,如示例 1 所示。該演算法使用的根(全域性物件)可以訪問 obj1 及其屬性“hello”。因此,它現在被標記了。
示例-1
var obj1 = {
pro1: "hello" // marked because it can be reached by root.
}假設將此物件賦值為 null 值,如示例 2 所示。然後,新賦值的“null”將被標記,而先前賦值的“屬性 hello”將被取消標記。因此,在標記階段結束時,我們可以得出結論:賦值為“null”的物件被標記,而賦值為“屬性 hello”的物件未被標記。
示例-2
obj1 = null // null will be marked(reachable) and hello will be unmarked(unreachable)
清除階段
顧名思義,它“清除”不可達的物件。在標記階段,我們看到帶有“屬性 hello”的物件未被標記,使其不可達。由於不可達的物件將被垃圾收集,因此此階段將垃圾收集帶有“屬性 hello”的物件。
Mark and Sweep 演算法也稱為追蹤式垃圾收集器,因為它追蹤程式直接或間接可訪問的整個物件集合。
迴圈不再是問題
在下面的示例中,當函式呼叫返回時,兩個物件 obj1 和 obj2 並沒有被可達的內容引用,因此有資格進行垃圾收集。因此,垃圾收集器將釋放物件 obj1 和 obj2 的記憶體。
示例
function f() {
var obj1 = {};
var obj2 = {};
obj1.p = obj2; // obj1 references obj2
obj2.p = obj1; // obj2 references obj1. This creates a cycle.
}
f();侷限性
有時手動決定何時以及釋放哪些記憶體非常方便。為了釋放物件的記憶體,必須將其明確地設為不可達。目前,無法在 JavaScript 中顯式觸發垃圾收集。
廣告
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP