Будет ли этот код вызывать утечку памяти? [Дубликат]

Я предпочитаю, чтобы прослушиватели событий были развернуты модульной функцией, а не сценарием прослушивателя событий уровня document. Итак, мне нравится ниже. Обратите внимание: вы не можете переадресовать элемент с одним и тем же прослушивателем событий, поэтому не беспокойтесь о прикреплении слушателя более одного раза - только один палец.

var iterations = 4;
var button;
var body = document.querySelector("body");

for (var i = 0; i < iterations; i++) {
    button = document.createElement("button");
    button.classList.add("my-button");
    button.appendChild(document.createTextNode(i));
    button.addEventListener("click", myButtonWasClicked);
    body.appendChild(button);
}

function myButtonWasClicked(e) {
    console.log(e.target); //access to this specific button
}

164
задан Cœur 9 April 2017 в 08:02
поделиться

4 ответа

По конкретному вопросу: «Будет ли сбор pclass быть собранным»: подписка на событие не влияет на сбор pClass (как издатель).

Для GC вообще (в частности, цель) : зависит от того, является ли MyFunction статическим или основанным на экземпляре.

Делегат (например, подписка на события) к методу экземпляра включает ссылку на экземпляр. Так что да, подписка на события предотвратит GC. Однако, как только объект, публикующий событие (pClass выше), имеет право на сбор, это перестает быть проблемой.

Обратите внимание, что это односторонний; т.е. если у нас есть:

publisher.SomeEvent += target.SomeHandler;

, тогда «издатель» сохранит «цель», но «цель» не сохранит «издателя».

Итак, нет: if pClass собирается собираться в любом случае, нет необходимости отписывать слушателей. Однако, если pClass долговечен (длиннее экземпляра с MyFunction), то pClass может сохранить этот экземпляр живым, поэтому будет необходимо отказаться от подписки, если вы хотите, чтобы цель была собрана.

Статические события, однако, по этой причине очень опасны при использовании с обработчиками на основе экземпляров.

182
ответ дан Marc Gravell 19 August 2018 в 08:43
поделиться
  • 1
    Ну, если вопрос «будет ли pClass быть собранным от мусора», тогда ответ «зависит от того, будет ли ...» на самом деле не является правильным. Это ни на что не зависит, как отмечает сам Марк. – Tor Haugen 18 November 2008 в 11:09
  • 2
    @Tor - справедливо - я уточню – Marc Gravell♦ 18 November 2008 в 11:54
  • 3
    Хотя делегат подписки на события указывает только один способ, абонент, который имеет намерение отказаться от подписки на событие, когда он будет сделан с ним, будет нуждаться в некоторой форме ссылки на издателя. Это может быть WeakReference, и в некоторых случаях это может быть хорошей идеей, но так часто, как не будет, это будет сильным. – supercat 13 April 2012 в 16:37
  • 4
    Отличный ответ, потому что он также затрагивает вторую половину вопроса (который не задавался): издатель остановит подписчик от GC'd. – Bob Sammers 23 June 2017 в 18:12
  • 5
    Да, и, как сказал @BobSammers, действительно может возникнуть проблема, если экземпляр с коротким сроком жизни, например Form / Window, подписывается на долговременный сервис, такой как Singleton, который предоставляет данные, например: Singleton затем сохраняет ссылку , и объекты хранятся в памяти, даже когда мы думаем, что они выгружены! Поэтому будьте очень осторожны при использовании событий. Мы злоупотребляли событиями для нашего большого программного обеспечения, и это очень сложно решить впоследствии. – Elo 28 March 2018 в 13:11

В тот момент, когда часть памяти больше не ссылается, она становится кандидатом на сбор мусора. Когда экземпляр вашего класса выходит за рамки, он больше не ссылается на вашу программу. Он больше не используется и, следовательно, может быть безопасно собран.

Если вы не уверены, что что-то будет собрано, задайте себе следующий вопрос: существует ли еще ссылка на него? Обработчики событий ссылаются на экземпляр объекта, а не наоборот.

6
ответ дан lvaneenoo 19 August 2018 в 08:43
поделиться

pClass будет собрано мусор. Однако, если фрагмент кода выше находится внутри другого класса, экземпляр этого класса может не очиститься, если вы не установите pClass в null.

0
ответ дан Picrofo Software 19 August 2018 в 08:43
поделиться

Да, pClass будет собираться мусором. Подписка на мероприятие не подразумевает, что какая-либо ссылка существует для pClass.

Так нет, вам не придется отсоединять обработчик, чтобы pClass собирался собирать мусор.

5
ответ дан Tor Haugen 19 August 2018 в 08:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: