`
crazier9527
  • 浏览: 994693 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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 onload="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.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
};
</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.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
    };
</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.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
    })();
};
</script>
<button id="element">"Click Here"</button>
</body>
</html>


3)避免闭包自身

<html>
<head>
<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");
}
</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/

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

分享到:
评论
1 楼 ylssww 2009-09-17  
我用各种内存检测软件比如 drip, js memory leaks detector, slEve,都查不出 IE 的内存泄露了,但用windows的 perfmon 工具检测 IE 进程仍然发现内存呈线性增长。即使只是对页面做几百次重复简单的刷新操作也会如此。
苦恼啊,不知道还会有什么原因。

richardroky@gmail.com

相关推荐

Global site tag (gtag.js) - Google Analytics