更新:我想我必须假设我的理解是正确的(可能,但如果你有更好的解释,请告诉我),它只需要Chrome 需要多花一点时间来 GC 分离的 DOM(我不知道应该花多长时间,很多时候它在很长一段时间内根本没有 GC)
全部:
我是 Javascript 内存管理的新手,当我阅读 Google Chrome(版本 65.0.3325.181(官方构建)(32 位)Windows 7)Devtool 教程时,有一个示例:
Discover detached DOM tree memory leaks with Heap Snapshots
var detachedNodes;
function create() {
var ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedNodes = ul;
}
document.getElementById('create').addEventListener('click', create);
我想原因是我还没有理解 DOM 在内存中是如何工作的。
我的想法是:每次点击,一个为create
构建的执行上下文,一个本地var ul进入那里引用堆中生成的UL对象,然后在堆中生成10个li,并连接UL 对象,然后 UL 对象被 detachedNode 引用。 而且我认为:在调用 create() 之后,detachedNode 和之前的 UL 对象之间的引用将被破坏(在单击之前调用 create() 期间生成),并且 document.createElement 只创建但不追加,所以那个 UL 对象应该被 GCed。
我想知道为什么堆中的 UL 对象不能被 GC?
最佳答案
如果我单击按钮一次,它会在该 ul
元素下创建一个 DOM 树,然后将其分配给全局 detachedNodes
变量(即 detachedNodes
将引用内存中的该对象)。
如果我再次单击它,它将为 detachedNodes
分配一个新的 ul
元素树,但现在旧的 ul
元素不会不再被引用。在这种情况下,第一次点击的 ul
树将被垃圾回收,因为不再有对它的引用。
所以回答你的问题:是的,第一个节点可以被垃圾收集。您链接到的 Google 文章似乎没有其他暗示;从我所见,它根本没有解决多次单击按钮的问题。
关于javascript - 这个内存泄露是怎么造成的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50031842/