OOM Killer к нам приходит

Думаю, каждый хотя бы раз сталкивался с Out Of Memory (OOM), а особо удачливые встречали OOM Killer. Страшней всего, когда это происходит без явных предпосылок в коде.

Скажу честно, проблемы с памятью обычно встречаю с чувством тревоги. Во-первых, чаще всего OOM происходит в приложениях с монолитной архитектурой, которые отличаются обилием функциональности и объемной кодовой базой. Пойди разберись, что именно могло пойти не по плану. Во-вторых, как правило, OOM — инцидент, и нет времени на долгие исследования. Наконец, объективно OOM случается крайне редко, чтобы каждый из нас был гуру в этом вопросе.

Чтобы побороть животные страхи, нужно немного разобраться в теме и попытаться классифицировать возможные ситуации. Определить, что перед нами: ошибка в коде или конфигурировании окружения. Поэтому не соглашайтесь уходить в исследование дампов, пока не узнаете всю предысторию возникновения OOM/Killer, иначе будете гоняться за призраками.

Многие знают, что в ОС для контроля памяти есть два основных показателя:

  • Сколько выделено. Сколько памяти ОС выделила процессу, включая данные кучи (heap), стека (stack), код процесса и используемых библиотек, но исключая память, которая была выгружена в swap. Показатель отражает фактическое состояние дел на текущий момент. В Linux — это Resident Set Size (RSS); в Windows — Working Set; в Kubernetes — container_memory_working_set_bytes.
  • Сколько запрошено. Сколько памяти процесс запросил у ОС. Совсем не факт, что запрошенный объем имеется сейчас в наличии или будет доступен в будущем. Это преднамеренное поведение, называемое резервированием (overcommitment). Показатель всегда больше RSS и отражает намерения процесса. В Linux — это VmData; в Windows — Private Bytes; в Kubernetes — нет аналога.

Что даёт понимание этих показателей?

  • Большой объем выделенной памяти не всегда свидетельство утечек. Часто приложение просто “жирное”, потому что так написано. В таких случаях проблема с OOM решается увеличением лимитов и заведением задач на оптимизацию кода.
  • Если нужно контролировать и предотвращать нежелательное поведение процесса, нужно следить за динамикой запрашиваемой памяти. Именно так я и сделал в своей задаче и стал контролировать VmData. Если процесс запрашивал больше лимита, он сразу прерывался.

Как анализировать расход памяти?

  • Пилообразный график. Это нормально, например, при наличии повторяющихся задач или сборщика мусора.
  • На продолжительном интервале видна тенденция к росту. Это нормально, например, при наполнении кэшей или повышении нагрузки.
  • Взрывной рост. Это нормально, например, при повышении нагрузки или выполнении тяжёлых операций (импорт/экспорт данных, формирование отчётов и т.д.).

Проанализируйте динамику роста, сопоставьте её с тем, что вы знаете про приложение и что этому предшествовало, и уже после этого выносите вердикт, является ли поведение аномальным и говорящим об утечке памяти.

А теперь вернемся к двум возможным ситуациям:

  • OOM — приложение упёрлось в лимит и завершилось самостоятельно.
  • OOM Killer — в системе возникла острая нехватка памяти. Защитный механизм ОС вызывает OOM Killer, который убивает самые “жирные” процессы. Под раздачу может попасть кто угодно, включая само приложение. Особенно неприятно, когда приложение умирает, а контейнер продолжает жить.

Первопричины обеих ситуаций схожие. Операции с памятью инертны: память выделяется/освобождается не сразу. Сборка мусора, активные аллокации, пиковые нагрузки, шумные соседи и т.п. Всё это может привести к тому, что упираемся в лимит быстрей, чем рассчитывали. Однако OOM Killer чаще всего означает ошибку конфигурирования окружения: limits не учитывает всплески или выбран неправильный QoS.

Приход OOM/Killer всегда сопровождается повышенной нагрузкой на CPU, т.к. в этот момент система судорожно пытается найти свободные страницы памяти.

Если анализ возможных причин указывает, что утечек нет, просто такой код и такие обстоятельства, то увеличиваем лимиты и спокойно идём оптимизировать код, анализируя снятый дамп памяти. Либо откатываемся. Так решается большинство ситуаций с OOM, и они не требуют героизма. В противном случае страдаем по полной.


Будьте бдительны. И да прибудет с вами Память!



Понравилась статья?

Посмею напомнить, что у меня есть Telegram-канал Архитектоника в ИТ, где я публикую материал на похожие темы примерно раз в неделю. Подписчики меня мотивируют, но ещё больше мотивируют живые дискуссии, ведь именно в них рождается истина. Поэтому подписывайтесь на канал и будем оставаться на связи! ;-)

Статьи из той же категории: