什么时候从内存中删除DOM?

r2_*_*118 11 html javascript dom memory-leaks memory-management

我正在开发一个创建和删除大量DOM的应用程序.我注意到尽管javascript堆内存保持不变,但浏览器选项卡中的进程内存不断增加.在测试应用程序中,我从父div创建并删除div.

http://jsfiddle.net/PSxPz/2/

<button onclick="createStuff()">Create</button>
<button onclick="deleteStuff()">Delete</button>
<div id="parent"></div>

function createStuff() {
    var parentDiv = document.getElementById('parent');
    for (var i = 0; i < 50000; i++) {
        var child = document.createElement('div');
        child.id = i;
        child.textContent = i;

        parentDiv.appendChild(child);
        child = null;
    }

    parentDiv = null;
}

function deleteStuff() {
    var parentDiv = document.getElementById('parent');
    for (var i = 0; i < 50000; i++) {
        var child = document.getElementById(i);
        parentDiv.removeChild(child);
        child = null;
    }

    parentDiv = null;
}
Run Code Online (Sandbox Code Playgroud)

我已经确认javascript堆没有泄漏与chrome dev工具(我是他们的新手所以我可能错过了一些东西).然而,该过程的记忆继续增加.从我读过的所有内容中,我怀疑移除的doms仍然在dom堆中.

其他帖子还说,浏览器最终会释放分配给删除的doms的内存.在上面的jsfiddle示例中,我多次点击创建和删除.我的javascript堆稳定在4.9MB.我的进程内存高达115MB.我等了30分钟,它根本没有下降.

问题

  1. 什么时候删除DOM元素完全从浏览器进程内存中删除?
  2. 有没有办法强制DOM垃圾收集?
  3. 是否有工具可以更深入地了解垃圾收集标记的doms?我在Chrome或IE中找不到一个.

谢谢您的帮助!

编辑

我使用了chrome dev工具,javascript堆没有增长.有趣的是,堆快照之间唯一的变化是(数组)对象.我的理解是,括号中的任何内容都由浏览器控制,并且超出了我的范围.每个后续的create-> delete删除旧的(数组)对象,并在删除期间创建一个新对象.

在时间轴中,我可以看到javascript堆是常量并且节点被清理干净,但是(shift + esc)所示的内存即使在节点计数下降后也不会下降.

在此输入图像描述 在此输入图像描述

看起来我正在尽我所能来确保清理我的javascript堆,但dom清理是我无法实现的,并且独立于javascript GC.这个陈述是否正确?

移除的doms是年轻一代的一部分吗?有没有办法设置这个堆大小的限制?我重复测试,直到我达到500MB仍然没有清理.我正在使用Chrome 35.0.1916.114顺便说一句.

小智 0

浏览器应该处理这个问题。113MB 的内存使用量仍然相当低。

但作为一个例子,请考虑这个: http: //jsfiddle.net/gildean/PSxPz/3/

<button class="create">Create</button>
<button class="delete">Delete</button>
<div id="parent"></div>

<script>
var parentDiv = document.querySelector('#parent');
var actions = {
    create: function createStuff() {
        var frag = document.createDocumentFragment();
        for (var i = 0; i < 10000; i++) {
            var child = document.createElement('div');
            child.id = i;
            child.textContent = i;
            frag.appendChild(child);
        }
        parentDiv.appendChild(frag);
    },
    delete: function deleteStuff() {
        while (parentDiv.children.length) parentDiv.removeChild(parentDiv.firstChild);
    }
};

Array.prototype.forEach.call(document.querySelectorAll('button'), function addListener(el) {
    el.addEventListener('click', function handler(event) {
        console.log(event.target.textContent + '!');
        actions[event.target.className]();
    });
});
</script>
Run Code Online (Sandbox Code Playgroud)