hostprofi.ru
Подобрать хостинг
Термин·буква O

OOM Killer

краткое определение

OOM Killer (Out of Memory Killer) — механизм ядра Linux, который при исчерпании физической памяти и свопа принудительно завершает процессы для предотвращения краша системы. Выбирает жертву по badness-оценке, учитывающей потребление памяти и настройки oom_score_adj.

OOM Killer (Out of Memory Killer) — механизм ядра Linux, который при исчерпании физической RAM и свопа принудительно завершает процессы, чтобы предотвратить полный крах системы. Активируется автоматически и действует за доли секунды — отключить его штатными средствами нельзя, но можно управлять приоритетами выбора жертв.

Как OOM Killer выбирает жертву

Ядро вычисляет для каждого процесса «оценку плохости» (badness score) от 0 до 1000. Чем выше оценка — тем больше вероятность, что процесс будет убит. Формула учитывает:

  • Размер виртуальной памяти процесса и всех его потоков.
  • Время работы: долгоживущие процессы получают скидку.
  • Запущен ли процесс от root (небольшая скидка).
  • Значение oom_score_adj — ручная корректировка от -1000 до +1000.

Процесс с наибольшим badness score получает SIGKILL и немедленно завершается. Его память освобождается для остальных процессов.

Управление через oom_score_adj

Каждый процесс имеет файл /proc/[PID]/oom_score_adj. Допустимые значения:

  • -1000 — процесс никогда не будет убит OOM Killer (oom_score_adj_min). Используй для системных демонов: sshd, базы данных.
  • 0 — стандартное значение, без корректировки.
  • +1000 — первый кандидат на уничтожение. Удобно для процессов, потеря которых некритична.
# Защитить процесс nginx от OOM Killer:
echo -1000 > /proc/$(pgrep nginx | head -1)/oom_score_adj

# Сделать процесс приоритетной жертвой:
echo 1000 > /proc/$(pgrep test-app)/oom_score_adj

В systemd-сервисах параметр задаётся через директиву OOMScoreAdjust в unit-файле — изменение сохраняется при перезапуске.

История

OOM Killer появился в ядре Linux в начале 1990-х как решение проблемы memory overcommit — оптимистичного выделения памяти, когда сумма запрошенной памяти превышает физическую RAM + swap. Ядро рассчитывает, что не все процессы используют всё выделенное одновременно. Алгоритм неоднократно переписывался — современная версия на основе badness score появилась в версии ядра 2.6.36 (2010).

OOM на VPS и контейнерах

На VPS и VDS ситуация усложняется: провайдер может использовать overcommit на уровне гипервизора. При OpenVZ-виртуализации лимиты памяти жёсткие — превышение вызывает OOM немедленно. При KVM — поведение стандартное Linux. В Docker-контейнерах лимит задаётся флагом --memory; при превышении Docker сам посылает SIGKILL без участия системного OOM Killer.

Предотвращение OOM в продакшне

Правильное планирование памяти: сумма requests.memory всех контейнеров/процессов не должна превышать доступную RAM. Добавить swap на VPS: 1-2 ГБ swap снижает риск OOM при кратковременных пиках, но не заменяет увеличение RAM. Инструменты анализа: ps aux --sort=-%mem (топ по памяти), pmap -x (карта памяти процесса), smem (суммарное потребление с учётом shared memory).

Настройка vm.overcommit_memory: 0 (default) — ядро разрешает overcommit с эвристикой, 1 — всегда разрешать (опасно), 2 — никогда (строгий режим). Для production-серверов с предсказуемой нагрузкой vm.overcommit_memory=2 + vm.overcommit_ratio=80 предотвращает OOM за счёт отказа в выделении памяти сверх 80% физической RAM. Проверка: /proc/sys/vm/overcommit_memory, применить через sysctl -w или /etc/sysctl.conf.

Как диагностировать OOM Killer

Записи OOM Killer в системном журнале:

# Поиск в dmesg:
dmesg | grep -i "oom"

# Поиск в journald:
journalctl -k | grep -i "oom\|killed process"

Запись выглядит примерно так: Out of memory: Kill process 12345 (nginx) score 892 or sacrifice child. После неё — список всех процессов с их oom_score на момент события. Если OOM срабатывает регулярно — решение не в настройке oom_score_adj, а в добавлении RAM, включении свопа или устранении утечек памяти в приложении.

Другие термины