首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有ID属性的动态DOM对象的IE9内存泄漏

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

Stack Overflow用户
提问于 2012-02-07 20:24:48
回答 2查看 2.2K关注 0票数 6

我注意到,将ID属性赋值给动态创建的DOM对象会导致IE9泄漏内存。还有没有其他人经历过这种情况,更重要的是,知道任何变通的方法?它不会在其他浏览器中泄漏,即使IE6通过了!

泄漏代码演示:

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

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

代码语言:javascript
复制
    <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),但由于某些我看不到的原因,这也导致了泄漏。

代码语言:javascript
复制
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]; 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-13 17:27:28

我在我的例子中找到了一个合适的解决方案,注意到在包含的测试页“运行”一段时间后重新加载它会导致内存使用量暂时保持不变(相对于重新加载之前的运行时间)。在那之后,它又开始上升。

因此,看起来,是的,IE不会在删除ID:d元素后完全删除该元素使用的资源,但如果将相同的ID再次添加到页面中,它显然会重用这些资源。

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

对于上面的测试代码:

计数;如果(计数> 1000)计数=0,则计数;

票数 2
EN

Stack Overflow用户

发布于 2012-02-10 02:46:47

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

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

在深度嵌套对象的情况下(即包含其他Swing对象的Swing表),我编写了一个递归方法,可以被我的所有Swing类使用,它将遍历任何Swing对象,将其中找到的每个对象设为空。

仅仅为了解决JVM的垃圾收集器中的一个bug,我不得不付出所有这些额外的努力,这很令人恼火,但它工作得很好。一旦我有了它,内存泄漏就消失了。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9176225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档