您的位置:首页 > Web前端 > JavaScript

IE,firefox内存溢出原因与解决方法

2017-10-11 18:43 405 查看
JavaScript 中的内存泄漏

JavaScript 是一种垃圾收集式语言,这就是说,内存是根据对象的创建分配给该对象的,并会在没有对该对象的引用时由浏览器收回。JavaScript 的垃圾收集机制本身并没有问题,但浏览器在为 DOM 对象分配和恢复内存的方式上却有些出入。

Internet Explorer 和 Mozilla Firefox 均使用引用计数来为 DOM 对象处理内存。在引用计数系统,每个所引用的对象都会保留一个计数,以获悉有多少对象正在引用它。如果计数为零,该对象就会被销毁,其占用的内存也会返回给堆。虽然这种解决方案总的来说还算有效,但在循环引用方面却存在一些盲点。

原因

1)循环引用导致了内存泄漏

[xhtml] view
plain copy

<html>  

<body>  

<mce: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"));  

};  

// --></mce:script>  

<div id="DivElement">Div Element</div>  

</body>  

</html>  

2)由外部函数调用引起的内存泄漏

[xhtml] view
plain copy

<html>  

<head>  

<mce: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"));  

}  

// --></mce:script>  

</head>  

<body onload="Leak()">  

<div id="myDiv"></div>  

</body>  

</html>  

3)闭包引起的内存泄漏

[javascript] view
plain copy

function parentFunction(paramA){  

    var a = paramA;  

    function childFunction(){  

        return a + 2;  

    }  

    return childFunction();  

}  

4)由事件处理引起的内存泄漏模式

[xhtml] view
plain copy

<html>  

<body>  

<mce:script type="text/javascript"><!--  

document.write("Program to illustrate memory leak via closure");  

window.onload=function outerFunction(){  

    var obj = document.getElementById("element");  

    obj.onclick=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  

};  

// --></mce:script>  

<button id="element">Click Me</button>  

</body>  

</html>  

解决方法
1)打破循环引用

[xhtml] view
plain copy

<html>  

<body>  

<mce:script type="text/javascript"><!--  

document.write("Avoiding memory leak via closure by breaking the circular reference");  

    window.onload=function outerFunction(){  

    var obj = document.getElementById("element");  

    obj.onclick=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  

    };  

// --></mce:script>  

<button id="element">"Click Here"</button>  

</body>  

</html>  

 

2)添加另一个闭包

[xhtml] view
plain copy

<html>  

<body>  

<mce:script type="text/javascript"><!--  

document.write("Avoiding a memory leak by adding another closure");  

window.onload=function outerFunction(){  

    var anotherObj = function innerFunction(){  

        // Some logic here  

        alert("Hi! I have avoided the leak");  

    };  

    (function anotherInnerFunction(){  

        var obj =  document.getElementById("element");  

        obj.onclick=anotherObj  

    })();  

};  

// --></mce:script>  

<button id="element">"Click Here"</button>  

</body>  

</html>  

3)避免闭包自身

[xhtml] view
plain copy

<html>  

<head>  

<mce:script type="text/javascript"><!--  

document.write("Avoid leaks by avoiding closures!");  

window.onload=function(){  

    var obj = document.getElementById("element");  

    obj.onclick = doesNotLeak;  

}  

function doesNotLeak(){  

    //Your Logic here  

    alert("Hi! I have avoided the leak");  

}  

// --></mce:script>  

</head>  

<body>  

<button id="element">"Click Here"</button>  

</body>  

</html>  

4)考虑用CollectGarbage()

[javascript] view
plain copy

jcl.MemFree = function(Mem){  

    Mem = null;  

    CollectGarbage();  

};  

检测软件
sIEve: 他是基于ie的内存泄露检测工具,需要下载运行,http://home.wanadoo.nl/jsrosman/
Leak Monitor: 他是基于firefox的内存泄露检测工具,https://addons.mozilla.org/firefox/2490/
个人建议

内存回收机制本身有问题,所以开发人员开发的时候尽量减少内存溢出。不要盲目的追求完美!

来源网址:http://blog.csdn.net/spring21st/article/details/5658309
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息