Как запустить действие при нехватке памяти в Linux?

Как запустить действие при нехватке памяти в Linux?

Итак, я подумал, что это будет довольно просто найти: модуль службы/ядра, который, когда ядро ​​замечает, что пользовательская память заканчивается, запускает какое-то действие (например, выгрузку списка процессов в файл, пингование какой-либо сетевой конечной точки и т. д.) в процессе, имеющем собственную выделенную память (чтобы он не потерпел неудачу при fork() или не пострадал от других обычных проблем OOM).

Я нашелУбийца ООМ, что, как я понимаю, полезно, но на самом деле не делает того, что мне нужно.

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

Есть ли вообще системный вызов, чтобы информироваться о чем-то подобном? Способ сказать ядру: "Эй, разбуди меня, когда у нас останется всего 128 МБ памяти"?

Я искал в Интернете и здесь, но ничего подходящего под это описание не нашел. Похоже, большинство людей используют опрос с задержкой по времени, но очевидная проблема в том, что это делает гораздо менее вероятным, что вы сможете узнать, какой процесс(ы) вызвал(и) проблему.

решение1

Да, ядро ​​Linux предоставляет для этого механизм:уведомление о нехватке памяти. Это задокументировано вhttps://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt, разделДавление памяти.

Короче говоря, вы регистрируете дескриптор файла eventfd, в /sys/fs/cgroup/memory/memory.pressure_levelкотором вы хотите получать уведомления. Эти уведомления могут быть low, medium, или critical. Типичным вариантом использования будет освобождение некоторых или всех внутренних кэшей в вашем процессе при получении уведомления, чтобы предотвратить надвигающееся уничтожение OOM.

решение2

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

В любом случае, вы можете запустить простое решение для мониторинга в пользовательском пространстве. У меня в прошлом были такие же требования к отладке/действию с низким потреблением памяти, и я написал простой bash, который делал следующее:

  • монитор длямягкий водяной знак:если использование памяти превышает этот порог, соберите некоторую статистику (процессы, свободная/используемая память и т. д.) и отправьте предупреждающее письмо;

  • монитор дляжесткий водяной знак:если использование памяти превышает этот порог, соберите некоторую статистику и завершите наиболее требовательные к памяти (или менее важные) процессы, а затем отправьте оповещение по электронной почте.

Такой скрипт будет очень легким и сможет опрашивать машину с небольшим интервалом (например, 15 секунд).

решение3

Текущий лучший ответ — для cgroups-v1. Для cgroups-v2 можно прослушивать события изменения файла в файле memory.events(документациясодержимого файла).

Поведение этого файла можно проверить с помощью нескольких команд оболочки:

# Spawn a new slice with memory limits to avoid OOMing the entire system
systemd-run --pty --user -p MemoryMax=1050M -p MemoryHigh=1000M bash

# Watch memory.events for changes and read when changed
inotifywait -e modify -m /sys/fs/cgroup$(cut -d: -f3 /proc/self/cgroup)/memory.events \
  | while read l; do echo $l; cat ${l// *}; done &
# Consume memory
tail /dev/zero

К сожалению, это, похоже, работает только если для cgroup действительно установлен лимит памяти. В качестве альтернативы можноприслушивайтесь к памяти.давление, но он не основан на cgroup (по крайней мере, для пользователей без прав root) и не столь быстро реагирует.

Связанный контент