Комментарий пользователя
Привет! Подозреваю утечку памяти: использую WeakMap для хранения метаданных, но объекты не освобождаются. Как проверить и где обычно скрывается проблема?
Ответ специалиста
Добрый день, Юлия, спасибо за вопрос! WeakMap не держит сильных ссылок, но утечка обычно происходит не в WeakMap, а в другом месте. Например, в замыканиях, списках подписчиков или незакрытых таймерах. Делайте диагностику:
Снимите heap-snapshot в Chrome DevTools (Memory → Take Heap Snapshot) до и после удаления ссылок на объект (удалили все наружные переменные, DOM-узлы). Сравните retaining tree и ищите сильные ссылки. Если необходимо, то переходите в официальное руководство по инструментам памяти в Chrome DevTools. Там описаны шаги по созданию.
Частые источники утечек:
- event listeners, привязанные к DOM, которые не удалены;
- таймеры setInterval/setTimeout, не очищенные;
- глобальные коллекции (Map, Array) где лежат ссылки;
- замыкания, где лексические переменные держат объекты.
Проверка на практике:
// пример: если вы сделали subscriptions.set(obj, handler)
subscriptions.set(obj, handler)
// при удалении нужно убрать listener и ссылку:
element.removeEventListener('click', handler)
subscriptions.delete(obj)
WeakMap особенности: вы не можете увидеть его содержимое напрямую. Убедитесь, действительно ли удалена единственная сильная ссылка на объект. Для демонстрации, создайте объект в блоке, отрежьте все внешние ссылки, сделайте GC (в DevTools → Collect garbage), затем снимите snapshot — если object все еще в retention tree, найдите цепочку удержания.
После удаления всех сильных ссылок и очистки слушателей объекты должны освобождаться. Если нет — смотрите retaining tree, там будет путь к корню удержания.
Дополнительно, более продвинутый инструмент для наблюдения за сборкой мусора — FinalizationRegistry. Он вызовется после того, как объект будет собран GC (хотя это и не всегда рекомендуется для прода).
Аналогичные инструменты есть и в других браузерах: в Firefox — Memory tool (снимки и анализ retaining tree), в Safari — Timeline → Memory (анализ аллокаций и пиков использования). Пользуйтесь ими по тому же сценарию: сделать снимок до и после удаления ссылок и сравнить.
Хотите писать код увереннее? Получайте советы и разборы по JavaScript в рассылке Академии Selectel.