论坛首页 AJAX版 JavaScript

关于ie6的DOM JScript内存泄漏介绍

浏览 483 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2008-03-16
ie6的js实现是基于JScript和DOM ActiveX各种分离部件实现的,所以回收内存自然有些问题,下面简单介绍下内存泄漏
例一
<html>
    <head><title>Queue Test 2</title>
    </head>
    <body>
        <script>
            /*global setTimeout */
            (function (limit, delay) {
                var queue = new Array(10);
                var n = 0;

                function makeSpan(n) {
                    var s = document.createElement('span');
                    document.body.appendChild(s);
                    var t = document.createTextNode(' ' + n);
                    s.appendChild(t);
                    return s;
                }

                function process(n) {
                    queue.push(makeSpan(n));
                    var s = queue.shift();
                    if (s) {
                        s.parentNode.removeChild(s);
                    }
                }

                function loop() {
                    if (n < limit) {
                        process(n);
                        n += 1;
                        setTimeout(loop, delay);
                    }
                }

                loop();
            })(10000, 10);
        </script>
    </body>
</html>

在ie6上面执行毫无问题,没有泄露,最多10个span,多了就remove,DOM和JScript没有交叉

例二

<html>
    <head><title>Queue Test 2</title>
    </head>
    <body>

        <script>
            /*global setTimeout */
            (function (limit, delay) {
                var queue = new Array(10);
                var n = 0;

                function makeSpan(n) {
                    var s = document.createElement('span');
                    document.body.appendChild(s);
                    var t = document.createTextNode(' ' + n);
                    s.appendChild(t);
                    s.onclick = function (e) {
                        s.style.backgroundColor = 'red';
                        alert(n);
                    };
                    return s;
                }

                function process(n) {
                    queue.push(makeSpan(n));
                    var s = queue.shift();
                    if (s) {
                        s.parentNode.removeChild(s);
                    }
                }

                function loop() {
                    if (n < limit) {
                        process(n);
                        n += 1;
                        setTimeout(loop, delay);
                    }
                }

                loop();
            })(10000, 10);
        </script>
    </body>
</html>

执行时候,打开任务管理器,大概每秒PF上升1M,原因是DOM元素span握有带closure的匿名函数,导致匿名函数空间不能释放

例三
<html>
    <head><title>Queue Test 2</title>
    </head>
    <body>
        <p>
            Queue Test 2 adds an event handler to each span. See <a href="http://www.crockford.com/javascript/memory/leak.html">http://www.crockford.com/javascript/memory/leak.html</a>
        </p>
        <script>
            /*global setTimeout */
            (function (limit, delay) {
                var queue = new Array(10);
                var n = 0;

                function makeSpan(n) {
                    var s = document.createElement('span');
                    document.body.appendChild(s);
                    var t = document.createTextNode(' ' + n);
                    s.appendChild(t);
                    s.onclick = function (e) {
                        s.style.backgroundColor = 'red';
                        alert(n);
                    };
                    return s;
                }

                function process(n) {
                    queue.push(makeSpan(n));
                    var s = queue.shift();
                    if (s) {
					s.onclick=null;
                        s.parentNode.removeChild(s);
                    }
                }

                function loop() {
                    if (n < limit) {
                        process(n);
                        n += 1;
                        setTimeout(loop, delay);
                    }
                }

                loop();
            })(10000, 10);
        </script>
    </body>
</html>

手动将带closure的匿名函数null后,再remove,内存无泄漏,最后有一purge函数,为Douglas Crockford所写

function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}

入门介绍帖,很可能在ie6打完hotfix后测试结果不一样
   
论坛首页 AJAX版 JavaScript

跳转论坛:
JavaEye推荐
    快速回复 引用上一条消息 (Alt+S)