內存管理之垃圾回收機制

1、內存生命週期

一、分配須要的內存(初始化值時)
二、使用分配的內存
三、不須要時將其內存釋放(垃圾回收器)
注意:
(1)全局變量的生命週期直至瀏覽器卸載頁面纔會結束。
(2)局部變量只在函數的執行過程當中存在,而在這個過程當中會爲局部變量在棧或堆上分配相應的空間,以存儲它們的值,而後再函數中使用這些變量直至函數結束局部變量就沒有存在必要了,能夠釋放它們佔用的內存html

2、垃圾回收機制

一、引用計數垃圾收集

(1)算法原理
經過在對象頭中分配一個空間來保存該對象被引用的次數。若是該對象被其它對象引用,則它的引用計數加一,若是刪除對該對象的引用,那麼它的引用計數就減一,當該對象的引用計數爲0時,那麼該對象就會被回收。
(2)算法理解算法

var p = new String("abc"); // 分配所需內存而且被p引用 abc這個字符串對象的引用計數值爲1.

clipboard.png

p = null; // 去除abc字符串對象的引用,abc字符串對象的引用計數減1

clipboard.png

重點理解
一、當對象的引用發生變化時,首先對原來引用對象的計數減一,再對新的引用對象的計數加一數組

var p = new String("abc");
var q = new String("efd");
p = q;

clipboard.png

二、當某個對象的引用計數減爲0時,collector須要遞歸遍歷它所指向的全部域,將它全部域所指向的對象的引用計數都減一,而後才能回收當前對象。在遞歸過程當中,引用計數爲0的對象也都將被回收,並把該對象的內存塊加入空閒鏈表中瀏覽器

var p = {
  phone:new String("1592xxxx"),
  address:new String("1130 kifer rd")
}
p = null;

clipboard.png

三、循環引用函數

function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o

  return "azerty";
}

f();

clipboard.png

(3)觸發時機
引用計數垃圾收集機制在引用計數變化爲0時即刻發生,並且只針對某一個對象以及它所依賴的其它對象。因此,咱們通常也稱呼引用計數垃圾收集爲直接的垃圾收集機制spa

二、標記-清除算法

(1)算法原理
這個算法把「對象是否再也不須要」簡化定義爲「對象是否能夠得到」。指針

標記階段是把全部活動對象都作上標記的階段。清除階段是把那些沒有標記的對象,也就是非活動對象回收的階段。經過這兩個階段,就能夠令不能利用的內存空間從新獲得利用code

這個算法假定設置一個叫作根(root)的對象(在Javascript裏,根是全局對象)。垃圾回收器將按期從根開始,找全部從根開始引用的對象,而後找這些對象引用的對象……從根開始,垃圾回收器將找到全部能夠得到的對象和收集全部不能得到的對象。htm

(2)算法理解對象

var teacher = {name:'Mary',age:35};
var student = {
                stu1:{name:'Amy',age:13},
                stu2:{name:'Dai',age:15}
              }

clipboard.png

標記階段

// 標記階段僞代碼
// 進行標記階段的處理
mark_phase(){
 for(r : $roots)
     mark(*r)
}
// 遞歸地標記經過指針數組能訪問到的對象。這樣就能把全部活動對象都標記上了。

 mark(obj){
   if(obj.mark == FALSE)
     obj.mark = TRUE
     for(child : children(obj))
       mark(*child)
 }

clipboard.png

清除階段

// 標記清除僞代碼
 1 sweep_phase(){
 2   sweeping = $heap_start // 從堆首地址開始
 3   while(sweeping < $heap_end) // 遍歷每一個標誌位
 4     if(sweeping.mark == TRUE) // 若是遍歷到已標記元素
 5       sweeping.mark = FALSE // 將標記清除
 6     else // 沒有遍歷到
 7       sweeping.next = $free_list // 將其插在空閒鏈表頭部
 8       $free_list = sweeping // 將空閒鏈表指針指向全部空閒鏈
 9   sweeping += sweeping.size // 繼續進行查找
10 }

clipboard.png

(3)觸發時機
垃圾收集器會按照固定的時間間隔或代碼執行中預約的收集時間,週期性地執行


參考文章
內存管理
引用計數算法
GC-標記清除算法
深刻理解做用域鏈(超讚)

相關文章
相關標籤/搜索