JavaScript 是一種垃圾收集式語言,這就是說,內存是根據對象的創建分配給該對象的,并會在沒有對該對象的引用時由瀏覽器收回。JavaScript 的垃圾收集機制本身并沒有問題,但瀏覽器在為 DOM 對象分配和恢復內存的方式上卻有些出入。
Internet Explorer 和 Mozilla Firefox 均使用引用計數來為 DOM 對象處理內存。在引用計數系統,每個所引用的對象都會保留一個計數,以獲悉有多少對象正在引用它。如果計數為零,該對象就會被銷毀,其占用的內存也會返回 給堆。雖然這種解決方案總的來說還算有效,但在循環引用方面卻存在一些盲點。
內存泄露的模式大概有以下幾種:
1.循環引用導致了內存泄漏,JavaScript 對象 obj 擁有到 DOM 對象的引用,表示為 DivElement。而 DOM 對象則有到此 JavaScript 對象的引用,由 expandoProperty 表示。可見,JavaScript 對象和 DOM 對象間就產生了一個循環引用。由于 DOM 對象是通過引用計數管理的,所以兩個對象將都不能銷毀。
obj=document.getElementById(”DivElement”);
document.getElementById(”DivElement”).expandoProperty=obj;
obj.bigString=new Array(1000).join(new Array(2000).join(”XXXXX”));
2.由外部函數調用引起的內存泄漏,通過調用外部函數 myFunction 創建循環引用。同樣,JavaScript 對象和 DOM
對象間的循環引用也會導致內存泄漏。
function myFunction(element)
{
this.elementReference = element;
// This code forms a circular reference here
//by DOM–>JS–>DOM
element.expandoProperty = this;
}
function Leak() {
//This code will leak
new myFunction(document.getElementById(”myDiv”));
}
3.Javascript閉包引起的內存泄漏,閉包功能非常強大,原因是它們使內部函數在外部函數返回時也仍然可以保留對此外部函數的變量的訪問。不幸的是,閉包非常易于隱藏 JavaScript 對象 和 DOM 對象間的循環引用。
function closureDemoParentFunction(paramA)
{
var a = paramA;
return function closureDemoInnerFunction (paramB)
{
alert( a +” “+ paramB);
};
};
var x = closureDemoParentFunction(”outer x”);
x(”inner x”);
Javascript內存泄漏工具:
1.Drip/sIEve
2. Javascript Leaks Detector
3. Leak Monitor
了解更多請閱讀:
http://www.ibm.com/developerworks/cn/web/wa-memleak/
http://djjchobits.javaeye.com/blog/375465
來源:http://adamlu.com/?p=418