Утечка памяти в проде: план действий
Вопрос
Память Node-сервиса медленно растёт, через сутки под убивается по OOM. Как найдёте утечку?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Подтверждаю по метрикам: растёт именно heap (`heapUsed`) после полных GC, а не RSS из-за буферов или нативных модулей
Снимаю несколько heap snapshot с интервалом (`--heapsnapshot-signal`, inspector, `v8.writeHeapSnapshot`) и сравниваю: какие объекты растут и кто их держит (retainers)
Типичные причины: кеш без лимита и TTL, Map по id запросов, слушатели событий без отписки, замыкания в таймерах, глобальные массивы
Учитываю, что снимок останавливает процесс и требует памяти: снимаю на выведенной из балансировки реплике
Воспроизвожу нагрузкой локально или на стейдже, фикс подтверждаю графиком памяти
Временная мера: лимит памяти и рестарт по порогу, но это не решение
Что могут спросить следом
- Чем RSS отличается от heapUsed?
- Почему
--max-old-space-sizeне лечит утечку? - Как найти утечку слушателей событий?
Разбор
Сначала убеждаюсь, что это утечка heap: смотрю heapUsed после полных сборок мусора. Если растёт только RSS, а heap стабилен, искать надо в буферах, нативных модулях или фрагментации. Если растёт heap, снимаю два-три heap snapshot с интервалом под нагрузкой: в Node можно запустить с --heapsnapshot-signal=SIGUSR2 или вызвать v8.writeHeapSnapshot(). В Chrome DevTools сравниваю снимки, смотрю, какие конструкторы растут, и по цепочке retainers вижу, кто держит объекты. Чаще всего это кеш без ограничения, Map, в которую кладут по запросу и не удаляют, слушатели событий без off, таймеры с замыканиями на большие объекты. Снимок тяжёлый: он останавливает процесс и временно требует памяти, поэтому делаю его на реплике, выведенной из балансировки. После фикса подтверждаю по графику памяти. Рестарт по лимиту памяти держу как страховку, но это не решение.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Кластер, воркеры, масштабирование»
- Консистентное хеширование с виртуальными узлами
- Балансировка least connections
- Плавный взвешенный round-robin как в nginx
- Код-ревью: сервис перед масштабированием в 4 инстанса
- Модуль cluster
- cluster внутри Kubernetes
- Память у воркеров cluster
- cluster или worker_threads