`
yiminghe
  • 浏览: 1465504 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

IE 内存泄露问题

阅读更多

 

1. ie 版本 <=6 循环引用出现:

 

<html>
<head>
    <script type="text/javascript">
        var myGlobalObject;
        // 产生循环引用,因此会造成内存泄露
        function SetupLeak() {

            //  First set up the script scope to element reference
            myGlobalObject = document.getElementById("LeakedDiv");

            //  Next set up the element to script scope reference
            document.getElementById("LeakedDiv").expandoProperty = myGlobalObject;

            // 或者通过事件属性注册形的闭包而造成的循环引用
            document.getElementById("LeakedDiv").onclick = function() {

            };

        }


        // 解开循环引用,解决内存泄露问题
        function BreakLeak() {
            return;
            document.getElementById("LeakedDiv").expandoProperty = null;
            document.getElementById("LeakedDiv").innerHTML = '';
            return confirm("ok?");
        }
    </script>
</head>

<body onload="SetupLeak()" onunload="BreakLeak()">
<div id="LeakedDiv">xxxxxxxxx</div>
</body>
</html>
 

 

上述代码展示了两种因为循环引用导致内存泄露的例子。

 

1. dom 节点的属性引用到自身节点,甚至包括不直接的引用,例如:

 

(function(){
var d={b:document.body}
var obj={doc:d}; // ← obj.doc.b === document.body
document.body.o=obj; // ← Circular loop: document.body.o.doc.b === document.body
})();
 

2. dom 节点的事件 handler 属性设置监听器函数,监听器函数的 [[scope]] 作用域会引用到该 dom 节点而造成隐蔽的循环引用。

 

(function(){
var b=document.body; // ← create a reference to document.body inside of the outer scope.
b.onclick=function() { // ← b.onclick refers to a function.
  // this function can access "b" due to closure
  // do something...
};
})();
 

注意事件使用 ie DOM2 的模式(attachEvent)注册事件时,由于没有直接和DOM属性接触,不会产生dom节点引用监听器函数,因而也不会产生循环引用,也不会带来内存泄露。

 

PS:类似 DOM,COM 在 ie 中也会因为循环引用而造成内存问题,譬如常见用于ajax 的 activeX:

 

(function(){
var x=getXHRobject();
x.onreadystatechange=function() { // ← create link from x (COM object) to anonymous function
  if(x.readystate==4){ // ← reference to x exists inside function scope, creating circular link.
    // do something.

    //消除循环引用
    x.onreadystatechange=null;
  }
};
})();

 

解决:


ajax 的问题解决就比较简单了,只要在 onreadystatechange 调用函数中将这个属性清空就行了。


而对于 dom ,则建议是尽可能的从 javascript object 引用 dom object,而不要从 dom object 引用到 javascript object,如果一定要这样做的话,下面给出了一段解决代码,在页面 unload 时清楚已设置的属性。

 

(function(){
var unLoaders=[];
myDomNode.object=new myObject(); // ← let’s say that this creates a leak somewhere
unLoaders.push(myDomNode); // ← save it for later
// create an “unload” function
var unload=function(){
  for(var i=unLoaders.length-1;i>-1;i–){
    unLoaders[i].object=null; // ← break the cycle
  }
};
// run the unload function on window.unload
YAHOO.util.Event.addListener(window,’unload’,unload);
})();
 

关键是:这个 bug 出现时即使刷新页面,内存仍然不会被释放


这个bug 已经在 ie >=7 以及 xp sp3上修复。详见 Memory Leaks in Microsoft Internet Explorer

 

 

2. ie removeChild 时出现孤立节点问题


ie 下面清除一个节点,调用 dom removeChild 的方法会出现该节点的内存并没有真正释放,ie内存也没有减少,(但是刷新页面会释放),所以对于ie要调用 parent.innerHTML = ""; 的方法来强制释放内存。(另外在之前还要清除该元素的所有监听事件,否则dom有引用仍然是释放不了,ie 中 Jscript 和 Dom 是分开的)。


详见:extjs-3.0 Element.js remove 方法

 

/**
         * Removes a DOM node from the document.  The body node will be ignored if passed in.
         * @param {HTMLElement} node The node to remove
         */
        removeNode : isIE ? function(){
            var d;
            return function(n){
                if(n && n.tagName != 'BODY'){
                    d = d || DOC.createElement('div');
                    d.appendChild(n);
                    d.innerHTML = '';
                }
            }
        }() : function(n){
            if(n && n.parentNode && n.tagName != 'BODY'){
                n.parentNode.removeChild(n);
            }
        }

 

总结:

 

一句话:尽量少使用 dom 自定义属性,尽量使用成熟类库注册事件。

 

参考资料:


对 ie 的内存缺陷算法感兴趣的话可以在以下文章中找到。


http://fins.iteye.com/blog/172891


http://oznyang.iteye.com/blog/180611?page=2


http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html


http://birdshome.cnblogs.com/archive/2005/02/16/104967.html

 

 

 

 

分享到:
评论

相关推荐

    ie内存泄露监控软件

    "ie内存泄露监控软件"是专门针对IE浏览器设计的一种工具,旨在检测和分析IE客户端可能出现的内存泄露情况。内存泄露是指程序在分配内存后未能正确释放,随着时间的推移,会导致系统资源逐渐耗尽,影响应用程序的性能...

    sIEve-0.0.8(IE Sieve_检测IE内存泄露情况)

    sIEve-0.0.8是一款专为解决IE内存泄露问题而设计的工具,它的主要目标是帮助开发者和用户检测并定位IE的内存泄露情况。 内存泄露通常发生在程序错误地分配和释放内存时。对于像IE这样的浏览器,它会加载各种网页和...

    IE内存泄露分析工具:sIEve/Drip

    标题中的“IE内存泄露分析工具:sIEve/Drip”指的是两个专门用于检测和分析Internet Explorer浏览器内存泄漏问题的工具。sIEve和Drip是独立的工具,但它们都致力于帮助开发者定位和解决IE浏览器中的内存管理问题。 ...

    ie内存泄漏检测软件

    **IE浏览器内存泄漏详解** IE浏览器,全称Internet Explorer,是微软公司开发的...JSLeaksDetector等专业工具的出现,为开发者提供了更方便的手段来诊断和修复IE浏览器的内存泄漏问题,提升了用户体验和系统的稳定性。

    Drip 检测IE内存泄漏

    标题 "Drip 检测IE内存泄漏" 提到的是一个专门用于检测 Internet Explorer (IE) 浏览器内存泄漏的工具,名为 Drip。内存泄漏是编程中的一个常见问题,尤其是在JavaScript环境中,由于IE浏览器的内存管理机制,这个...

    脚本IE内存泄露检测.rar

    标题中的“脚本IE内存泄露检测.rar”表明这是一个专门针对Internet Explorer浏览器的JavaScript内存泄漏检测工具。内存泄漏是编程中常见的问题,特别是在处理大量数据或长时间运行的网页应用时,可能导致浏览器性能...

    sIEve IE内存泄露监控

    `sIEve IE内存泄露监控` 是一款专注于检测和分析Internet Explorer(简称IE)浏览器内存泄漏问题的工具。它作为一个绿色软件,无需安装即可直接运行,为用户提供了一种方便的方式来检测网页在IE浏览器中可能导致性能...

    测试JavaScript在IE中的内存泄露

    在压缩包子文件的文件名"IE内存泄露测试"中,我们可以推测包含的资源可能是一个测试套件、指南、或者是一个实际的工具,用于帮助开发者在IE环境下进行内存泄露的模拟和检测。 要有效地测试和解决JavaScript在IE中的...

    javascript内存泄露问题的解析

    这表明内存泄漏问题的存在。 在Question2中,我们不仅创建了DOM元素,还添加了点击事件响应函数。在Mozila和Opera浏览器中,虚拟PF利用率与Question1相同,但是在IE浏览器中,我们可以看到由于内存泄漏而产生的每秒...

    IE内存泄漏检测工具 Drip-0.5

    **IE内存泄漏检测工具Drip-0.5详解** 在Web开发中,内存泄漏是一个常见的问题,尤其是在使用老版本的Internet Explorer(IE)浏览器时。IE由于其独特的内存管理机制,常常会出现JavaScript(JS)内存泄漏的情况,这...

    内存泄露检测工具

    10. IE Leak Detector (Drip/IE Sieve):是一个网页开发工具,用于检测 IE 中的内存泄漏问题。 IE Leak Detector 工具可以检测 IE 中的内存泄漏问题,并提供了详细的错误信息,以便开发者快速解决问题。 11. ...

    IE内存监控sIEve-0.0.8

    "IE内存监控sIEve-0.0.8" 是一个针对Internet Explorer浏览器的内存监控工具,其版本号为0.0.8。这个工具专门设计用于检查和分析IE浏览器在运行时的内存使用情况,帮助用户或开发者识别可能导致性能问题或者内存泄漏...

    js内存泄露问题

    5. **Internet Explorer特定的泄漏**:IE浏览器在历史上存在一些特有的内存泄漏模式,例如DOM元素与CSS样式表对象之间的异常引用,或者ActiveX对象的不当使用。 为了检测和解决JavaScript内存泄漏,可以使用一些...

    IE内存泄露之JQuery html(),append()

    本文将深入探讨标题中提到的"IE内存泄露之JQuery html(),append()"这一问题,它涉及到JavaScript库JQuery在Internet Explorer浏览器中的特定使用场景下可能导致内存泄露的现象。 首先,我们要理解什么是内存泄露。...

    IE 内存检测工具

    sIEve是一款专为检测IE内存泄漏设计的开源工具。它通过监控IE浏览器进程,收集内存分配和释放的信息,分析并报告可能存在的内存泄漏问题。sIEve能帮助开发者识别哪些对象或脚本导致了内存占用的异常增长。使用方法...

    Android webview 内存泄露的解决方法

    Android webview 内存泄露的解决方法 最近在activity嵌套webview显示大量图文发现APP内存一直在涨,没法释放内存,查了很多资料,大概是webview的一个BUG,引用了activity导致内存泄漏,所以就尝试传递...

    css样式和内存泄漏

    文件“ie内存泄漏.doc”和“IE浏览器.doc”可能专注于这些特有问题的解析。内存泄漏的解决方案可能包括正确使用闭包、避免全局变量、利用window周期事件进行资源清理等。 “常见兼容问题.doc”可能汇总了各种类型的...

    内存泄漏检测工具

    该工具可以帮助开发者识别和定位IE浏览器中的内存泄漏问题,提升网页在IE下的性能。 4. **使用方法** 用户可以通过`IEJSLeaksDetector.exe`来运行该工具。首先,打开需要测试的网页,然后运行检测工具,它将分析...

Global site tag (gtag.js) - Google Analytics