r2_*_*118 11 html javascript dom memory-leaks memory-management
我正在开发一个创建和删除大量DOM的应用程序.我注意到尽管javascript堆内存保持不变,但浏览器选项卡中的进程内存不断增加.在测试应用程序中,我从父div创建并删除div.
<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分钟,它根本没有下降.
问题
谢谢您的帮助!
编辑
我使用了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)