1. 程式人生 > 實用技巧 >JavaScript中的垃圾收集機制

JavaScript中的垃圾收集機制

1.簡單介紹

  js中存在著自動垃圾收集機制,也就是說執行環境會複製管理程式碼執行過程中使用的記憶體,不需要開發人員去手動跟蹤。

  垃圾收集機制的原理:找出不再使用的變數,釋放其佔用的資源。

  為什麼需要垃圾回收?:防止記憶體洩露,一些不再需要使用的變數仍然儲存在記憶體中,就會造成記憶體洩露問題。

  垃圾收集器必須跟蹤某個變數是否有用,對於不需再使用的變數打上標記以便回收,用於標識無用變數的策略通常有兩種:標記清除,引用計數

2.標記清除

  當變數進入環境的時候,就將這個變數標記為“進入環境”。從邏輯上來說,永遠不能釋放進入環境的變數所佔用的記憶體,因為只要執行流進入相應的環境,就可能會用到這些變數。當變數離開環境後,將變數標記為“離開環境”

  垃圾收集器在執行的時候會給儲存在記憶體中的所有變數都加上標記(可以使用任何標記方式),然後,它會去掉環境中的變數及被環境中的變數引用的變數的標記,在這項工作完成之後再被加上標記的變數就視為準備刪除的變數。最後,垃圾收集器完成記憶體清除工作,銷燬掉帶標記的值並回收它們所佔用的空間。

  大部分瀏覽器使用的都是標記清除式的垃圾收集策略,只不過時間間隔可能會不同。

  

function test(){
    var a=0;
    var b=0;
   //a,b被標記為進入環境          
}

test();
//函式執行完畢,a,b被標記為離開環境。等待垃圾收集器回收

  

3.引用計數

  這個策略在現在的瀏覽器中不常見,引用計數是指跟蹤記錄每個值被引用的次數。

  當聲明瞭一個變數並且將一個引用型別值賦值給這個變數時,該值得引用次數就是1,。如果同一個值又被賦給另一個變數,則該值的引用次數加一。如果包含對這個值引用的變數取了別的值,則該值的引用次數減一。當該值的引用次數變為0的時候,說明沒有辦法訪問這個值了,因此就可以將其佔用的空間回收。當垃圾收集器再次執行的時候,就會釋放那些引用次數為0的值所佔的記憶體。

  但是這個策略有一個嚴重的問題:迴圈引用。

  迴圈引用是指物件a包含一個指向物件b的指標,而物件b也包含一個指向物件a的引用。

function problem(){
    var obA = new Object();
    var obB = new Object();
    
    ObA.someOtherObject = ObB;
    ObB.anotherObject = ObA;
}

  在這個例子中,,obA和obB通過各自的屬性相互引,它們的引用次數都為2。

  如果我們採用標記清除策略,函式執行完畢以後這兩個物件就離開了作用域,會被垃圾收集器視為準備刪除的變數。

  但是如果採用引用計數策略,當函式執行完畢後,它們還將繼續存在,因為它們的引用次數不可能減為0。假如重複多次呼叫這個函式,就會造成大量記憶體得不到回收,導致記憶體洩露。