IE,firefox內存溢出原因與解決方法

JavaScript 中的內存泄漏
JavaScript 是一種垃圾收集式語言,這就是說,內存是根據對象的創建分配給該對象的,並會在沒有對該對象的引用時由瀏覽器收回。JavaScript 的垃圾收集機制本身並沒有問題,但瀏覽器在爲 DOM 對象分配和恢復內存的方式上卻有些出入。
Internet Explorer 和 Mozilla Firefox 均使用引用計數來爲 DOM 對象處理內存。在引用計數系統,每個所引用的對象都會保留一個計數,以獲悉有多少對象正在引用它。如果計數爲零,該對象就會被銷燬,其佔用的內存也會返回 給堆。雖然這種解決方案總的來說還算有效,但在循環引用方面卻存在一些盲點。


原因

1)循環引用導致了內存泄漏
<html>
<body>
<script type="text/javascript">
document.write("circular references between JavaScript and DOM!");
var obj;
window.onload = function(){
    obj=document.getElementById("DivElement");
document.getElementById("DivElement").expandoProperty=obj;
    obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
};
</script>
<div id="DivElement">Div Element</div>
</body>
</html>


2) 由外部函數調用引起的內存泄漏
<html>
<head>
<script type="text/javascript">
document.write(" object s between JavaScript and 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"));
}
</script>
</head>
<body οnlοad="Leak()">
<div id="myDiv"></div>
</body>
</html>


3) 閉包引起的內存泄漏
function parentFunction(paramA){
    var a = paramA;
    function childFunction(){
        return a + 2;
    }
    return childFunction();
}


4) 由事件處理引起的內存泄漏模式
<html>
<body>
<script type="text/javascript">
document.write("Program to illustrate memory leak via closure");
window.οnlοad=function outerFunction(){
    var obj = document.getElementById("element");
    obj.οnclick=function innerFunction(){
    alert("Hi! I will leak");
    };
    obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
    // This is used to make the leak significant
};
</script>
<button id="element">Click Me</button>
</body>
</html>


解決方法
1)打破循環引用
<html>
<body>
<script type="text/javascript">
document.write("Avoiding memory leak via closure by breaking the circular reference");
    window.οnlοad=function outerFunction(){
    var obj = document.getElementById("element");
    obj.οnclick=function innerFunction()
    {
        alert("Hi! I have avoided the leak");
        // Some logic here
    };
    obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
    obj = null; //This breaks the circular reference
    };
</script>
<button id="element">"Click Here"</button>
</body>
</html>


2)添加另一個閉包
<html>
<body>
<script type="text/javascript">
document.write("Avoiding a memory leak by adding another closure");
window.οnlοad=function outerFunction(){
    var anotherObj = function innerFunction(){
        // Some logic here
        alert("Hi! I have avoided the leak");
    };
    (function anotherInnerFunction(){
        var obj =  document.getElementById("element");
        obj.οnclick=anotherObj
    })();
};
</script>
<button id="element">"Click Here"</button>
</body>
</html>


3)避免閉包自身

<html>
<head>
<script type="text/javascript">
document.write("Avoid leaks by avoiding closures!");
window.οnlοad=function(){
    var obj = document.getElementById("element");
    obj.onclick = doesNotLeak;
}
function doesNotLeak(){
    //Your Logic here
    alert("Hi! I have avoided the leak");
}
</script>
</head>
<body>
<button id="element">"Click Here"</button>
</body>
</html>


4)考慮用 CollectGarbage()
jcl.MemFree = function(Mem){
    Mem = null;
    CollectGarbage();
};


檢測軟件
sIEve : 他是基於ie的內存泄露檢測工具,需要下載運行, http://home.wanadoo.nl/jsrosman/

Leak Monitor : 他是基於firefox的內存泄露檢測工具,https://addons.mozilla.org/firefox/2490/

個人建議
內存回收機制本身有問題,所以開發人員開發的時候儘量減少內存溢出。不要盲目的追求完美!

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