【发布时间】:2017-03-31 10:18:59
【问题描述】:
编辑:请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=707544 了解相关问题和有关该错误的信息。
从现在开始不需要回答这个问题,但保留问题以供参考。
Element.getElementsByTagName 在 Chrome 中返回 HTMLCollection。
它阻止GC收集被调用或引用的元素。
尽管在 Detached DOM 树中没有发现任何内容,但节点数(可能还有堆大小)意外增加。
下面展示了点击下面提供代码的页面中的按钮和强制GC 交替的结果。 (Major GC/DOM GC 后堆大小下降,但节点计数不下降)
以及第一次分配和强制GC后的内存信息。
在我看来,那些 HTMLCollection 可能充当缓存/占位符。由于它的 parent 是一个 临时 元素,因此即使移除和收集了这些元素,也会保留不必要的 HTMLCollection 副本。
在 Win10 的 Chrome 57.0.2987.133 和 Chromium 59.0.3058.0 上观察到。
可重现的代码:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="content"></div>
<input type="button" id="button">
<script type="application/javascript">
var button = document.getElementById('button');
button.addEventListener('click', function() {
var content = document.getElementById('content');
for (var i = 0; i < 2000; i++) {
var el = document.createElement("div");
//var no_leak = el.querySelectorAll('SPAN'); // NodeList
var leak = el.getElementsByTagName('SPAN'); // HTMLCollection
content.appendChild(el);
el.remove();
}
});
</script>
</body>
</html>
【问题讨论】:
-
GC 通常安排在您的密集计算完成后运行。我知道阈值是adjusted in v51,但也许它有一个相关的变化recently as well。考虑在crbug.com 上提交错误报告,并使用易于重现的测试用例 html。
标签: javascript google-chrome memory-leaks garbage-collection htmlcollection