> Каковы причины утечек памяти в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Swetec

Стек: JavaScript

> Пример ответа

Короткий ответ

Основные причины утечек памяти в JavaScript: глобальные переменные, забытые таймеры и колбэки, замкнутые ссылки в замыканиях, утечки из DOM (detached DOM nodes), ссылки на удалённые элементы через WeakMap/WeakSet, а также некорректное использование сторонних библиотек. В браузере это приводит к росту потребления памяти, фризам и падению производительности.

Подробное объяснение

Утечки памяти в JavaScript возникают, когда объекты остаются достижимыми из корневых узлов (global object, DOM tree), хотя они больше не нужны. Основные механизмы:

  1. Глобальные переменные: объявление без let/const или присвоение к window создаёт неудаляемую ссылку.
  2. Таймеры и интервалы: setInterval или setTimeout с колбэком, который захватывает большие объекты, не очищаются.
  3. Замыкания: функция сохраняет ссылку на внешнюю область видимости, даже если она больше не используется.
  4. Detached DOM nodes: удаление элемента из DOM, но сохранение ссылки на него в JavaScript (например, в массиве или замыкании).
  5. События и подписки: добавление обработчиков без их удаления (особенно в SPA при переходах).
  6. Циклические ссылки: в старых браузерах (IE) GC не мог обработать циклы между JS и DOM.

Современные движки (V8, SpiderMonkey) используют mark-and-sweep, но не могут освободить память, если объект достижим через корень.

На практике

  • Используйте WeakMap и WeakSet для кэширования данных, связанных с DOM-элементами.
  • Всегда очищайте таймеры и интервалы в useEffect (React) или при уничтожении компонента.
  • Удаляйте обработчики событий через removeEventListener или используйте AbortController.
  • Избегайте глобальных переменных - используйте модули или IIFE.
  • Для профилирования используйте Chrome DevTools: Memory → Heap snapshot, сравнение снимков до и после действий.
  • В Node.js следите за утечками через process.memoryUsage() и утилиты типа clinic.

Пример кода

JAVASCRIPT
// Утечка через глобальную переменную
function leak() {
leaked = { data: new Array(1000000) }; // без let/const - глобальная
}
// Утечка через таймер
function startTimer() {
const hugeData = new Array(1000000);
setInterval(() => {
console.log(hugeData.length); // hugeData не освободится
}, 1000);
}
// Detached DOM node
const detachedNodes = [];
document.querySelectorAll('.item').forEach(el => {
detachedNodes.push(el); // ссылка сохраняется после удаления из DOM
});
// Правильный подход с WeakMap
const cache = new WeakMap();
function processElement(el) {
if (!cache.has(el)) {
cache.set(el, { data: '...' });
}
// при удалении el из DOM, запись автоматически удалится из cache
}

Как отвечать на собеседовании

Начните с краткого определения утечки памяти, затем перечислите основные причины, упорядочив от самых частых к редким. Приведите конкретный пример из практики (например, утечка в React при подписке на WebSocket без отписки). Покажите понимание работы GC: mark-and-sweep, поколенческая сборка. Упомяните инструменты профилирования. Для senior-уровня важно продемонстрировать системный подход: как предотвращать утечки на этапе архитектуры, а не только исправлять.

Что проверяет интервьюер

  • Понимание механизма сборки мусора и достижимости объектов.
  • Знание типичных паттернов утечек в браузере и Node.js.
  • Умение применять инструменты отладки (DevTools, heap snapshots).
  • Способность проектировать код с учётом управления памятью (WeakMap, паттерн dispose).
  • Опыт работы с фреймворками (React, Vue) и их особенностями (эффекты, хуки).

Типичные ошибки

  • Путать утечку памяти с фрагментацией или медленной работой GC.
  • Считать, что delete на свойстве объекта решает проблему (не всегда, если есть другие ссылки).
  • Игнорировать утечки в сторонних библиотеках (например, старые версии jQuery).
  • Не учитывать утечки через замыкания в колбэках асинхронных операций (Promise, async/await).
  • Думать, что null присвоение переменной гарантирует сборку - GC может сработать не сразу.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью