Out of Memory Killer (OOM Killer) – это механизм ядра Linux, который освобождает оперативную память при ее исчерпании за счет принудительного завершения некоторых запущенных процессов.
При исчерпании памяти в системе, ядро Linux вызывает OEM killer, который по определенным правилам выбирает один процесс и убивает его. Освободившаяся память передается в распоряжение ядра, которое может предоставить ее другим процессам.
Если процесс убивается OOM Killer, в логе /var/log/messages будет такая запись:
$ cat /var/log/messages | grep "Out of"
Out of Memory: Killed process 123 (postgres) score 904 or sacrifice child
OOM killer убивает процессы сигналом SIGKILL, не предоставляя им возможность корректно завершить свое выполнение (сохранить данные, вызвать другие процессы). Поэтому результат работы OOM killer часто приводит к тяжелым последствиям.
Частое появление OOM killer говорит о нестабильности работы системы и требует от администратора внимательного анализа причин возникновения событий исчерпания памяти.
Чтобы завершить процесс, Linux вызывает функцию out_of_memory. В функции out_of_memory вызывается функция select_bad_process, которая позволяет выбрать процесс для завершения. Все запущенные процесс оцениваются с помощью функции badness. Badness выбирает процесс по правилам, основанным на вычисленной репутацим каждого процесса (oom_score).
Вы можете вывести репутацию процесса по его PID (например, для ID процесса 1764):
$ cat /proc/1764/oom_score
728
Чем выше репутация процесса, тем больше вероятность того, что именно его завершит OOM Killer.
Вы можете отключить OOM Killer в Linux (не рекомендуется в большинстве случаев):
$ sudo cat /proc/sys/vm/panic_on_oom
По умолчанию тут указан 0. Это значит, что OOM Killer включен.
Чтобы отключить его:
$ sudo echo 1 > /proc/sys/vm/panic_on_oom
Если вы не хотите отключать OOM Killer, но хотите гарантировать, что определенный процесс никогда не будет принудительно завершен, нужно увеличить его репутацию.
Выведите текущую репутацию процесса:
$ cat /proc/1764/oom_score
Можно увеличить, или уменьшить репутацию процесса, добавив в файл oom_adj значение от -16 до +15.
Например, так:
$ sudo echo -5 > /proc/1764/oom_adj
$ cat /proc/1764/oom_score
Если нужно совсем отключить OOM Killer для процесса, нужно указать в oom_adj значение -17.
$ sudo echo -17 > /proc/1764/oom_adj
$ cat /proc/1764/oom_score
Однако нужно понимать, что при перезапуске процесса, его PID изменится. И эта репутация будет переназначена другому процессу с таким же PID.
Можно динамически определять PID процесса и уменьшать его репутацию:
$ pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; done
Но гораздо удобнее задать репутацию в файле сервиса юнита службы systemd:
[Service] OOMScoreAdjust=-500