Итак, я подумал, что это будет довольно просто найти: модуль службы/ядра, который, когда ядро замечает, что пользовательская память заканчивается, запускает какое-то действие (например, выгрузку списка процессов в файл, пингование какой-либо сетевой конечной точки и т. д.) в процессе, имеющем собственную выделенную память (чтобы он не потерпел неудачу при 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) и не столь быстро реагирует.