Сборка мусора и утечки памяти
Вопрос
Как работает сборка мусора в JavaScript и откуда во фронтенде берутся утечки памяти?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Объекты в куче, освобождение автоматическое, по достижимости от корней
Mark-and-sweep, циклы не проблема; поколения в V8
Утечка это ненужный, но достижимый объект
Примеры: таймеры, слушатели, подписки, detached DOM, кеши без лимита, замыкания
Лечение: очистка в `useEffect`, `AbortController`, `WeakMap`, ограничение кешей
Поиск: heap snapshots и сравнение, Retainers, фильтр Detached
Что могут спросить следом
- Утекают ли объекты с циклическими ссылками?
- Как найти, кто удерживает объект?
- Зачем нужны WeakRef и FinalizationRegistry?
Разбор
Образцовый ответ: «Память в JS освобождает сборщик мусора. Критерий: достижимость. От корней, это глобальный объект, стек вызовов, активные замыкания, сборщик обходит граф ссылок, помечает всё, до чего дошёл, и освобождает остальное. Это mark-and-sweep, поэтому циклические ссылки сами по себе не проблема. V8 ещё делит кучу на поколения: молодые объекты чистит часто и быстро, пережившие переносит в старое поколение. Утечка в JS это объект, который больше не нужен, но остаётся достижимым. Типичные источники во фронтенде: интервал без clearInterval, слушатель на window без снятия, подписка на стор или сокет без отписки, удалённый из DOM узел, на который осталась ссылка в массиве, кеш без ограничения, замыкание, держащее большой объект. Лечится дисциплиной очистки: функция очистки в useEffect, AbortController для слушателей, WeakMap для данных, привязанных к объектам, лимиты на кеши. Ищу через вкладку Memory: снимок до, повтор действия, снимок после, сравнение и разбор цепочки Retainers».
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.