Что такое OOM Killer

Обновлено и опубликовано Опубликовано:

OOM Killer —
простыми словами

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

Чтобы увидеть, применялся ли в системе oom killer, используем dmesg:

dmesg -T | egrep -i 'killed process'

Будет выполнен анализ лога, и если killer запускался, мы увидим что-то на подобие:

[Wed Sep 18 12:03:36 2024] Out of memory: Killed process 785923 (postmaster) total-vm:1261472kB, anon-rss:15000kB, file-rss:4kB, shmem-rss:1025780kB, UID:20 pgtables:4320kB oom_score_adj:0

Если упрощенно, данная строчка нам говорит, что 18 сентября в 12:03 был остановлен процесс с идентификатором 785923. Имя процесса postmaster (PostgreSQL).

Какой процесс уничтожить. Чтобы понять, какой процесс можно остановить, OOM Killer запускает внутреннюю функцию oom_badness(). Данная функция получает значения занимаемого объема оперативной памяти в процентном эквиваленте для каждого из запущенных процессов, после чего эти значения модифицируются в соответствии с алгоритмом:

  • Прибавляется половина очков от всех дочерних процессов, которые имеют собственную виртуальную память.
  • Если приоритет процесса > 0, то очки умножаются на 2. Приоритет процесса может иметь значения от -20 до +20. В данном случае +20 это самый низкий приоритет.
  • Очки делятся на коэффициент, связанный с процессорным временем, чем более активнее процесс и чем больше процессорного времени он использует, тем больше будет его коэффициент.
  • Очки делятся на коэффициент, связанный с временем жизни процесса, чем больше времени прошло с момента запуска, тем выше будет это значение.
  • Для процессов, запущенных от имени root, служебных учеток или процессов ввода-вывода очки делятся на 4.
  • Для процесса, при выделении памяти у которого произошла ошибка out of memory и процессам имеющим с ним общую память, очки делятся на 8.
  • Все что получилось выше умножается на 2^oom_adj. Где oom_adj это специальный коэффициент, имеющий значения от -17 до +15.

* текст с описание алгоритма взят со страницы сайта medium.com (за исключением последнего пункта. На практике установлено, что минимальное значение не -16, а -17).

Полученный результат может иметь значения от 0 до 1000, поделив который на 10 мы получаем процент вероятности, что процесс будет убит (0 или 100%).

В итоге, на основе полученных чисел функция oom_badness составляет список всех процессов, которых должен убить oom killer. Как правило, в этот список попадают те, кто больше всех потребляет памяти, но при этом наименее активен, а также имеет самое короткое время жизни.

Как смотреть значения OOM для процесса.

Для нас интересны значения 3-х опций:

cat /proc/<PID>/oom_adj

cat /proc/<PID>/oom_score_adj

cat /proc/<PID>/oom_score

* где <PID> — идентификатор процесса. Подробнее о работе с процессами Linux читайте в статье Работа с процессами в Linux.

Разберем их подробнее:

  1. oom_adj — числовой модификатор от -17 до 15. Является более старым подходом для определения приоритетов киллера и может быть изменен в файле /proc. Чем ниже значение, тем меньше вероятность, что процесс будет уничтожен.
  2. oom_score_adj  — более новый файл для настройки приоритетов. Используется для настройки через systemd. Его изменение приводит к автоматическому перерасчету параметра oom_adj. Имеет возможность задать значения от -1000 до 1000.
  3. oom_score — текущий OOM-счет для процесса. Его значение варьируют от 0 до 1000.

Как можно менять приоритеты для киллера.

Мы можем изменить значение для oom_adj на лету, например:

echo -17 > /proc/<PID>/oom_adj

Данная команда приведет к тому, что процесс не будет убит с помощью OOM-киллера.

Или наоборот:

echo 15 > /proc/<PID>/oom_adj

... повысит вероятность до 100%, что при необходимости процесс будет уничтожен.

Однако, данная настройка будет действовать до перезапуска процесса. Для указания перманентного значения лучше всего использовать опцию OOMScoreAdjust для systemd. Например, мы хотим изменить приоритет для сервиса nginx — создаем drop-in файл:

systemctl edit nginx

И добавляем:

[Service]
OOMScoreAdjust=-300

* вероятность уничтожения nginx будет немного понижена.

Перезапускаем процесс, чтобы изменения применились:

systemctl restart nginx

 



Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

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

Root   MySQL   BIND   Сервер   HAProxy   POP3   OpenVZ   Реестр Windows   QoS   FSMO   SSD   Интернет шлюз   DHCP   Mail.ru   CIFS/SMB   Golang   FPS   SQL   USB   Mango АТС  
.....

Реклама