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

Javascript 具有ID属性的动态DOM对象的IE9内存泄漏,javascript,internet-explorer,memory-leaks,internet-explorer-9,Javascript,Internet Explorer,Memory Leaks,Internet Explorer 9,我注意到,为动态创建的DOM对象分配ID属性值会导致IE9泄漏内存。有没有其他人经历过这种情况,更重要的是,知道任何解决办法?它不会在其他浏览器中泄漏,甚至IE6也不会 泄漏代码的演示: 它只是不断地从表中添加和删除行,并为每一行分配一个ID以供以后查找 如果没有“row.id=eid;”,则不会发生泄漏 回到我的JavaSwing时代(是的,我已经老了),JVM也有类似的问题。因为垃圾收集器将无法清理嵌套在其他Swing对象中的Swing对象,从而导致内存泄漏 我曾经通过显式地将每个Swing

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

泄漏代码的演示:

它只是不断地从表中添加和删除行,并为每一行分配一个ID以供以后查找

如果没有“row.id=eid;”,则不会发生泄漏


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

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

对于深度嵌套的对象(即包含其他Swing对象的Swing表),我编写了一个递归方法,我的所有Swing类都可以使用该方法,它将向下遍历任何Swing对象,并将其中找到的每个对象都设为NULL

为了解决JVM垃圾收集器中的一个bug,我不得不进行所有这些额外的工作,这让我很恼火,但它工作得很好。一旦我把它放好,内存泄漏就消失了


尝试类似IE9的东西可能值得一试。强制DOM对象为空,因为它们不再需要,这可能会为您解决这个问题。还有我们其他人…:-)

在我的例子中,我发现在包含的测试页面“运行”一段时间后重新加载该页面会导致内存使用暂时保持不变(相对于重新加载之前的运行时间)。之后它又开始上升

因此,似乎是的,IE在元素被删除后并没有完全删除ID:d元素所使用的资源,但是如果相同的ID再次添加到页面中,IE显然会重新使用这些资源

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

对于上述测试代码:

++计数;
如果(计数>1000)计数=0

是否尝试使用
setAttribute
分配id?理论上它应该没有什么区别,但我们永远不知道…我试过了,但没有区别。问题是这个代码的运行速度慢,或者IE占用了太多内存?您是否尝试过在DOM中插入一次,首先在某个变量中收集所有新的HTML?没有对速度的抱怨,只有无限的内存使用。如果我让它继续运行,它最终将达到32位Windows上的虚拟地址空间限制,然后代码停止运行。我还听到其他人说IE9实际上解决了旧IE版本中的内存泄漏问题,所以这可能是IE9独有的新泄漏。我猜是新的代码库。
    <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>
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];