垃圾回收機制、閉包、以及內存泄漏

Js中的垃圾回收機制

1.標記清除
工作原理:當變量進入環境時被垃圾回收器標記爲‘進入環境’,離開環境時被標記爲‘離開環境’,標記爲‘離開環境’的變量被統一回收。
工作流程:
1.垃圾回收器將內存中所有存在的變量做標記
2.將內存中存在環境中的變量以及環境變量所引用的變量的標記去除
3.仍然存在標記的變量被視爲‘離開環境’的變量
4.垃圾回收器完成內存清除工作,清除所有帶標記的變量並回收其內存空間。

2.引用計數(低IE版本9.0)
工作原理:機制就是跟蹤一個值的引用次數,當聲明一個變量並將一個引用類型賦值給該變量時該值引用次數加1,當這個變量指向其他一個時該值的引用次數便減一。當該值引用次數爲0時就會被回收。
工作流程:

  1. 聲明瞭一個變量並將一個引用類型的值賦值給這個變量,這個引用類型值的引用次數就是1。
  2. 同一個值又被賦值給另一個變量,這個引用類型值的引用次數加1.
  3. 當包含這個引用類型值的變量又被賦值成另一個值了,那麼這個引用類型值的引用次數減1.
  4. 當引用次數變成0時,說明沒辦法訪問這個值了。
  5. 當垃圾收集器下一次運行時,它就會釋放引用次數是0的值所佔的內存。

內存泄漏問題
在IE9版本以前,DOM、BOM元素對象並非原生JS對象,而是由C++編寫的COM對象形式實現,而COM對象採用的爲該計數垃圾回收策略,從而容易循環引用導致內存泄漏問題;
那麼何爲循環引用?

function f(){
var a={},
var b={},
a.prop =b;
b.Prop = a;
}
該例子中,a的屬性引用b,b的屬性引用a,從而以計數原則,a、b的引用次數均爲2,而且永遠爲2,垃圾回收機制無法回收該對象,從而造成的內存泄漏。

!!!DOM簡單事件引起的內存泄漏
這裏牽扯到閉包的問題,我們知道閉包是能使用外部變量的內部函數,因爲閉包默認引用了外部函數的變量,所以及其容易循環引用造成內存泄漏問題。
window.onload = function outerFunction(){
var obj= document.getElementById(“eleId”);
obj.onclick = function innerfunction(){
console.log(obj.id);
}
}
該例子中,dom元素obj使用了引用了閉包,而閉包默認引用了外部變量(其中包含obj),如此一來,便形成了一個循環引用。
解決方案:
window.onload = function outerFunction(){
var obj= document.getElementById(“element”);
var id = obj.id;//將obj副本保存於變量id中,則不會使obj元素處理程序的閉包創建循環引用
obj.onclick = function innerfunction(){
console.log(id);
}
obj= null;//手動斷開 obj 對 document.getElemengById(“element”)的引用
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章