Вопрос 1: Почему отдельные элементы dom
не собираются сборщиком мусора в следующем скрипте
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>button {padding: 5px 10px;float: left;margin: 10px 5px;background-color: #4653eb;color: #fff;font-weight: bold;cursor: pointer;border: none;outline: none;}button:hover {background-color: #208c2c;}span {float:left;margin-right:2px}</style>
</head>
<body>
<button id="show-btn">Show</button>
<div id="container"></div>
<script src="js.js"></script>
</body>
</html>
// js.js
"use strict";
(function () {
class Test {
constructor(outerDom) {
this._container = null;
//this.onClick = null;
this._init(outerDom);
}
_init(outerDom) {
const container = document.createElement('div');
const clearButton = container.appendChild(document.createElement('button'));
clearButton.id = 'clear-btn';
clearButton.textContent = 'Clear';
//this.onClick = this._removeDomsOnClick.bind(this);
//clearButton.addEventListener('click', this.onClick);
clearButton.addEventListener('click', this._removeDomsOnClick.bind(this));
for (var i = 0; i < 2000; i++) {
container.appendChild(document.createElement('span')).textContent = 'text inside span';
};
outerDom.textContent = '';
outerDom.appendChild(container);
this._container = container;
}
// Click event handler
_removeDomsOnClick(e) {
// Detaching event target from parent
//e.target.parentNode.removeChild(e.target); // #1
// Removing event listener
//e.target.removeEventListener('click', this.onClick);
//this.onClick = null;
// Detaching clear button's parent node (It will remove clear button(ie event target) and 2000 spans)
this._container.parentNode.removeChild(this._container);
// Not needed(AFAIK). But making sure no reference kept.
this._container = null;
}
}
document.getElementById('show-btn').addEventListener('click', function () {
// Not keeping any refernece to newly created instance
new Test(document.getElementById('container'));
});
}());
При нажатии button#show-btn
создается и прикрепляетсяdom
, который содержит button#clear-btn
и 2000 span
элементов.
При нажатии на button#clear-btn
он отсоединит ранее добавленные dom
(который содержит button#clear-btn
(то есть e.target
) и 2000span
элементов).
Но эти отсоединенные doms
не являются сборщиком мусора (если только сначала не отсоединить button#clear-btn
(то есть e.target
) от его родителя). Я не вижу никаких ссылок на эти doms
в сценарии. Даже если event
имеет ссылку на target
, path
и т. Д., Я ожидаю, что он завершит сборку мусора после завершения события click.
Снимки кучи и временные шкалы распределения
1
Страница только что загружена.
button#clear-btn
и span
элементы еще не созданы.
куча: 1
2
После нажатия button#show-btn
Родитель dom
, содержащий button#clear-btn
и 2000 span
элементы созданы и прикреплены к видимым dom
50KB
назначенная память
куча: 2
временная шкала: 2
3a
После нажатия button#clear-btn
.
Ранее созданный родительский элемент dom
, содержащий элементы button#clear-btn
(т.е. e.target
) и 2000 span
, отсоединяется от видимых dom
. Но они не являются сборщиком мусора .
50KB
память не освобождается.
куча: 3a
временная шкала: 3a
3b
Примечание: Первый button#clear-btn
(то есть e.target
) отсоединено от родителя dom
(раскомментируйте строку # 1).
После нажатия button#clear-btn
.
Ранее созданный родительский элемент dom
, содержащий button#clear-btn
(т.е. *Элементы 1101 *) и 2000 span
отсоединены от видимых dom
. Они сборщик мусора .
50KB
память уменьшена до 10KB
.
куча: 3b
сроки: 3b
Вопрос 2: Даже в 3b
почему 10KB
не освобождается?
Почему MouseEvent
объект остается в памяти. И вот его родители UIEvent
, Event
и т. Д. globalThis in Window
держат его. Что это такое? Зачем хранить ссылку?
И что такое this in system
?
Временная шкала: 3bExpanded
(Ответ на вопрос 1 также может быть ответом на это)
Вопрос 3: В heap:1
почему есть 6 HTMLBodyElement
и 4 CanvasRenderingContex2D
и 7 HTMLDocument
и в heap:2
почему 9 HTMLDivElement
При перезагрузке страницы,иногда эти цифры увеличиваются (26 HTMLBodyElement
...?). Я пытался Empty Cache and Hard Reload
. Но без разницы. Если открыть в новой вкладке вместо перезагрузки, они вернутся к нормальному.
В 3a
я попытался удалить приемник событий из button#clear-btn
перед отсоединениемparent dom
(Проверьте комментарии в файле js). Но без разницы.
Я попробовал форсировать collect garbage
вариант. Но отдельные домены не собираются.
Консоль пуста.
Точки останова не установлены.
Chrome 78.0.3904.87
Chrome Canary 80.0.3959.0
Incognito Mode with no extensions