Мне известно о ulimit, и я знаю, как ограничить память для процесса, который я запускаю явно или начинаю использовать скрипт. Но в этом случае у меня есть сервис, который управляется и запускается systemd.
Как я могу ограничить его максимальную память и убить ее (или даже лучше: предотвратить ее выделение памяти (вернуть NULL в malloc
/ realloc
)) когда он достигает максимума использования памяти?
В справочная страница для systemd.exec
есть список инструкций LimitXXXX и удобная таблица, в которой они сравниваются с ulimit
варианты, в виде setrlimit()
системный вызов.
Чтобы ограничить все адресное пространство процесса (ulimit -v
) использовать LimitAS=
. В противном случае, чтобы ограничить только стек (ulimit -s
) использовать LimitSTACK=
или сегмент данных (ulimit -d
) использовать LimitDATA=
Согласно setrlimit()
manpage, эти ограничения приведут к сбою выделения дополнительной памяти. СТЕК и AS завершат программу с помощью sigsegv, если предел достигнут и стек должен увеличиваться (а программа не справилась с этим).
Systemd поддерживает ограничение использования памяти с помощью параметра MemoryLimit, как описано в: https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html
То, как система обрабатывает ситуацию, когда максимально разрешенная память (для каждой службы) исчерпана, зависит как от базовой реализации cgroups, так и от способа, которым systemd реализует управление ресурсами; Я предполагаю, что процесс будет убит (через убийцу OOM).
Для лимитов, аналогичных ulimit:
man systemd.exec
...
LimitAS=(like ulimit -v)
...
LimitRSS=(like ulimit -m)
...