Одним из способов ограничения памяти для процесса, запускаемого в шеле (bash, sh) является утилита ulimit. Можно использовать ulimit с ключем -v:
ulimit -v
Такой ключ ограничивает количество памяти, доступной процессу. Если приложение требует больше памяти для корреткной работы, а ulimit эту программу ограничивает, скорее всего процесс умрет (завершится abort).
Есть по крайней мере два варианта
Первый, мы уже фактически рассмотрели - это ограничение памяти процессу ulimit -v.
Второй вариант - если запускаемая программа рекурсивно обращается к различным библиотекам или другим процессам. В таком случае нужно контролировать размер стека через ключ -s
ulimit -s
Команда ulimit использует "жесткие" (hard) и так называемые софт (soft) лимиты. Хард лимиты могут быть только уменьшены, увеличить использование ресурсов по жесткому лимиту нельзя. Лично я не рекомендовал бы менят значения хард лимитов, а использовать софт лимиты. Что бы задать значения софт лимитов, ulimit можно использовать так:
ulimit -Sv
Если нужно только посмотреть текущие значения:
ulimit -Sa
Вывод на обычном сервере с Ubuntu:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) 1024
pending signals (-i) 31030
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 31030
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
В сети еще есть интересный скрипт на Perl для ограничения памяти: http://coldattic.info/page/resourcelimit/
Для старых версий Linux (не помню точно с какой версии ядра ключ -m перестал работать), можно контролировать размер "резидентной" памяти:
ulimit -t 300s -m 100000k your_program ...
В примере выше для программы "your_program" задается ограничение по времени выполнения (300 милисекнд) и 100 тысяч килобайт памяти. Как только программа выйдет за разрешенные лимиты, стандартный вывод ошибок STDERR сообщит о проблеме и программа завершится.
Есть альтернативный метод - использовать cgroups:
cgcreate -g memory:/my_group
echo $(( 100 * 1024 * 1024 )) > /sys/fs/cgroup/memory/my_group/memory.limit_in_bytes
echo $(( 1000 * 1024 * 1024 )) > /sys/fs/cgroup/memory/my_group/memory.memsw.limit_in_bytes
Я думаю из приведенного выше примера уже интуитивно понятно что задано и что сделано. Тем не менее, поясню. Мы создали специальную группу с названием "my_group" и ограничили ресурсы (память) для любых процессов, запускаемвых в этой группе. В данном случае мы поставили ограничение в 100 мебагайт физической памяти и 1000 мегабайт в pagefile (файл подкачки, он же swap).
Как запустить приложение your_program в группе my_group:
cgexec -g memory:my_group your_program
Что бы пользоваться cgroups на Debian или Ubuntu, нужно предварительно устанеовить пакет:
apt install cgroup-bin
И иак же нужно отредавтировать конфигурацию загрузчика (в данном примере - grub):
vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"
Далее сохранить конфиг и обноить конфигурацию загрузчика:
sudo update-grub