Предотвращает ли setInterval внутри объекта сбор мусора при удалении объекта?

Я работаю над небольшим проектом Websocket (используя Socket.io), где я использую такой класс:

function myClass() {
    // start server sync
    window.setInterval(this.update.bind(this), 14);

    // listen for socket.io events
    io.on('my-event', doStuff);
}

В массиве хранится несколько экземпляров этого класса. Через некоторое время экземпляры удаляются так:

myArr.splice(index, 1);

Массив является единственным местом, в котором я храню экземпляры, поэтому я подумал, что они будут удалены сборщиком мусора после удаления их из массива.

Вместо этого я заметил, что они все еще реагируют на мои события веб-сокета. Мне интересно, если интервал препятствует удалению объекта, потому что он связан с объектом окна. Нужно ли очищать интервал перед удалением экземпляра класса?

Или прослушиватель событий предотвращает удаление объекта?

2 ответа

Решение

... экземпляры удаляются так:

myArr.splice(index, 1);

... Вместо этого я заметил, что они все еще реагируют на мои события веб-сокета. Мне интересно, если интервал препятствует удалению объекта, потому что он связан с объектом окна. Нужно ли очищать интервал перед удалением экземпляра класса?

Да, вам нужно сделать больше очистки. Вам нужно:

  • Очистите интервал, чтобы очистить ресурсы, связанные с ним, и заставить его освободить ссылку на функцию, созданную this.update.bind(this) (который в свою очередь имеет ссылку на объект, сохраняя его в памяти).

  • Удалите все прослушиватели событий (например, события веб-сокетов), которые будут удалять их ссылки на функции обработчика событий, которые, вероятно, имеют ссылки на объект, который хранит его в памяти.

  • Убедитесь, что любые другие ссылки на объект, прямые или косвенные (например, в любых других связанных функциях), также освобождаются.

Да, ссылка на значение или область действия функции предотвращает ее использование.

Фактически, указатели на функции и объекты и области являются одной из основных причин утечек памяти в JavaScript, наиболее частой в этой категории являются замыкания, часто связанные с обратными вызовами событий (включая таймеры в этой категории).

Если вы хотите, чтобы ваш объект был мусорным, обязательно отмените регистрацию всех обработчиков событий и удалите таймеры (обратите внимание, что обработчики событий удаляются при удалении элемента из DOM и не сохраняют ссылку на него).

Другие вопросы по тегам