OOM Killer в Linux

🕒 3 мин.

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

Теория

Любой запущенный процесс в системе потребляет оперативную память. И если память заканчивается, то система может, либо зависнуть, либо завершить один из её процессов. И чтобы система не зависла, в ней существует механизм, который отвечает за завершение процессов в случае нехватки памяти — OOM Killer (Out-Of-Memory Killer).

OOM Killer выбирает процесс для завершения смотря на баллы oom_score. А именно, при нехватки памяти, будет завершён процесс с наибольшим количеством баллов oom_score.

Факторы увеличивающие oom_score:

  • Потребление памяти. Самый главный фактор, чем больше памяти (RSS и swap) использует процесс, тем больше у него балов и шансов на завершение.
  • Дочерние процессы. При завершении процесса-родителя часто завершаются и все его потомки, чтобы освободить больше памяти. Поэтому, если у процесса много дочерних процессов, которые тоже потребляют память, тем больше у него балов.

Факторы уменьшающие oom_score:

  • Время работы. Чем дольше процесс работает, тем меньше у него баллов и шансов быть завершённым.
  • Системные процессы. Процессы, запущенные от имени root, имеют небольшое преимущество перед пользовательскими.

Мы, как IT-специалисты, можем также повлиять на некоторые факторы:

  • Корректировка оценки OOM (oom_score_adj). Это самый важный управляемый параметр. Задаётся от -1000 до 1000.
    • -1000: Процесс никогда не будет убит. Используется для критически важных системных процессов (например, systemd).
    • 0: Базовая оценка (по умолчанию для большинства процессов).
    • 1000: Процесс будет убит первым, если использует хоть сколько-нибудь памяти.
  • Приоритет процесса (nice). Процессы, запущенные с низким приоритетом (высокое nice-значение), получают больше баллов и шансов быть завершёнными.

Исходя из этой логики, больше всего шансов быть завершённым у процесса, который:

  1. Использует очень много физической памяти и swap.
  2. Имеет высокое значение oom_score_adj.
  3. Является молодым и запущен от имени обычного пользователя.
  4. Имеет низкий приоритет (высокое nice-значение).

Управление механизмом

Включение и выключение OOM Killer

Полностью выключить OOM Killer в системе нельзя. Но можно перенастроить поведение системы во время нехватки памяти.

echo vm.panic_on_oom = 1 >>/etc/sysctl.conf # вместо OOM Killer -> kernel panic
echo vm.panic_on_oom = 0 >>/etc/sysctl.conf # по умолчанию -> OOM Killer

Для применения изменений выполните:

sysctl -p

Параметр oom_score_adj

Параметр oom_score_adj корректирует итоговое значение oom_score, прибавляя или отнимая баллы у процесса.

Можно напрямую поменять значение параметра oom_score_adj используя файловую систему /proc:

echo -500 > /proc/<pid>/oom_score_adj

Либо управлять через настройки службы SystemD:

[Service]
# Защита от OOM Killer
OOMScoreAdjust=-500
# При завершении - перезапустить
OOMPolicy=restart

Также в системе есть файл /proc/PID/oom_adj — это устаревший механизм корректировки, от -17 до +15. В современных системах использовать нужно именно файл oom_score_adj.

Приоритет процесса nice

Косвенно на балы oom_score влияет приоритет процесса.

Можно вручную запустить процесс с указанным nice:

# Запустить команду с низким приоритетом
nice -n 19 <команда>

# Запустить команду с высоким приоритетом
sudo nice -n -10 <команда>
  • Установка отрицательных значений (более высокого приоритета) требует прав root (sudo).

Изменение nice уже работающего процесса (renice):

# Понизить приоритет
renice -n 19 -p <pid>

# Повысить приоритет (требует root)
sudo renice -n -5 -p <pid>

Также можно задать приоритет для процессов определённой службы:

[Service]
Nice=19

Как посмотреть текущие баллы у процесса

Скрипт для просмотра oom_score у топ 20 процессов:

for pid in /proc/[0-9]*; do
    pid_num=${pid##*/}
    if [ -r "$pid/oom_score" ]; then
        read score < "$pid/oom_score" 2>/dev/null
        printf "%5d %7d\n" "$score" "$pid_num"
    fi
done | sort -rn | head -20

Для просмотра значений у отдельных процессов:

cat /proc/<pid>/oom_score
cat /proc/<pid>/oom_score_adj

Источники

  1. Linux — начинающим. Что такое OOM Killer и как он работает
  2. Настраиваем Out-Of-Memory Killer в Linux для PostgreSQL

Если понравилась статья, подпишись на мой канал в VK или Telegram.

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять
Отказаться
Политика конфиденциальности