具有ID属性的动态DOM对象的IE9内存泄漏

时间:2012-02-07 12:24:48

标签: javascript internet-explorer memory-leaks internet-explorer-9

我注意到为动态创建的DOM对象分配ID属性值会导致IE9泄漏内存。有没有其他人经历过这个,更重要的是,知道任何解决方法?它在其他浏览器中不泄漏,即使IE6通过!

泄漏代码的演示:

它只是连续地从表中添加和删除行,并为每行分配一个ID,以便稍后查找。

没有“row.id = eid;”

就不会发生泄漏
    <html>
    <head>
        <script type="text/javascript">

        function addRow(tbl, index) {
            var row = tbl.insertRow(index);
            var eid = "loongrowid" + count;
            row.id = eid;

            for (var i = 0; i < 9; i++) {
                row.insertCell(i);
            }

            return row;
        }

        function removeTableRow(tbl, index) {
            var row = tbl.rows[index];
            tbl.deleteRow( index );

        }

        var count = 1;

        function fillRow(row){
            row.cells[0].innerHTML = '<input type="checkbox"' + ' checked="checked"' + ' />';
            for (var i = 1; i < 9; i++) { 
                row.cells[i].innerHTML = count + " c";
            }
            ++count;
        }

        var added = false;

        function dostuff() 
        {
            var tbl = document.getElementById("tbl");
            var i;

            if (added)
            {
                for (i = 0; i < 20; ++i)
                {
                    removeTableRow(tbl,1);
                }
            }
            else
            {
                for (i = 0; i < 20; ++i)
                {
                    var row = addRow(tbl, i+1);
                    fillRow(row);
                }
            }

            added = !added;
            setTimeout(dostuff, 1); 
        }
        </script>
    </head>
    <body onload="setTimeout(dostuff, 1)">
    <h1 id="count">TESTING</h1>
    <table id="tbl" style="width:100%;">    
    <tr>
        <th>selected</th>
        <th>date</th>
        <th>time</th>
        <th>place</th>
        <th>device</th>
        <th>text</th>
        <th>state</th>          
        <th>status</th>
        <th>quality</th>
    </tr>
    </table>
    </body>
</html>

我注意到从表行中删除所有单元格会导致内存泄漏缩小,所以我猜IE从表中删除后会保留该行。

我还尝试了一种解决方法,将创建的表行添加到Javascript对象中以用作散列表,而不是依赖于getElementById(row.id),但由于某种原因我也看不到它。 / p>

var hash = [];

    // when creating row
    row.extid = eid; // Note: this by itself causes no leak
hash[eid] = row; 

    // when removing row
delete hash[row.extid]; 

2 个答案:

答案 0 :(得分:2)

我发现在我的情况下找到一个合适的解决方案,注意到在“运行”一段时间之后重新加载包含的测试页导致内存使用暂时保持不变(相对于重新加载之前运行的时间)。之后它再次开始上升。

所以,似乎是的,IE在删除元素后不会完全删除ID:d元素所使用的资源,但如果再次向页面添加相同的ID,它显然会重新使用这些资源。

Ergo,只需确保添加和删除的ID是有限集的一部分,而不是无限制的集。测试页面使用严格增加的基于整数的ID,我的原始问题案例使用类似的序列号ID。幸运的是,在两种情况下都很容易将它们固定在有限的范围内。

对于上面的测试代码:

++计数; if(count> 1000)count = 0;

答案 1 :(得分:0)

回到我的Java Swing时代(是的,我已经老了),JVM有一个类似的问题。因为垃圾收集器无法清除嵌套在其他Swing对象内部的Swing对象,从而导致内存泄漏。

我曾经通过将每个Swing对象显式设置为NULL来解决这个问题,因为不再需要它们。

对于深度嵌套的对象(即包含其他Swing对象的Swing表),我编写了一个递归方法,可以被所有Swing类使用,这些类将遍历任何Swing对象,对每个对象进行NULL操作发现在。

令人恼火的是,为了解决JVM的垃圾收集器中的错误,我不得不经历所有这些额外的努力,但它工作得非常好。一旦我有了这个,内存泄漏消失了。

尝试尝试与IE9类似的东西可能值得。由于不再需要将DOM对象强制为NULL,可以为您解决此问题。我们其他人也......: - )