
При написании программы бывают случаи, когда неконтролируемая программа поглощает половину моей оперативной памяти (обычно из-за практически бесконечных циклов при создании больших структур данных), и это приводит к тому, что система становится настолько медленной, что я даже не могу завершить программу-нарушителя. Поэтому я хочу использовать ulimit, чтобы автоматически завершать мою программу, когда она использует ненормальный объем памяти:
$ ulimit -a
core file size (blocks, -c) 1000
data seg size (kbytes, -d) 10000
scheduling priority (-e) 0
file size (blocks, -f) 1000
pending signals (-i) 6985
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) 10000
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) 6985
virtual memory (kbytes, -v) 100000
file locks (-x) unlimited
$ ./run_program
но почему моя программа все равно использует больше оперативной памяти, чем заданный лимит (да, я запускаю программу в той же оболочке bash)?
Я что-то не так понял насчет ulimit?
решение1
Ваш пример должен работать так, как вы думаете (программа завершается после потребления слишком большого объема оперативной памяти). Я только что провел небольшой тест на своем сервере оболочки:
Сначала я ограничил свои лимиты до ДЕЙСТВИТЕЛЬНО низких:
ulimit -m 10
ulimit -v 10
Это приведет к тому, что почти все будут убиты ls
, date
а другие мелкие команды будут расстреляны еще до того, как начнут действовать.
Какой дистрибутив Linux вы используете? Ваша программа использует только один процесс или порождает множество дочерних процессов? В последнем случае ulimit не всегда может быть эффективным.
решение2
ulimit -m
больше не работает. Используйте ulimit -v
вместо этого.
Причина в том, что ulimit
вызывает setrlimit, ичеловек setrlimitговорит:
RLIMIT_RSS Указывает предел (в байтах) резидентного набора процесса (количество виртуальных страниц, резидентных в ОЗУ). Этот предел действует только в Linux 2.4.x, x < 30, и там влияет только на вызовы madvise(2), указывающие MADV_WILLNEED.
решение3
Это работает только в одном сеансе bash, если только вы не добавите это в свой .bash_profile, и не будет применяться к уже запущенным процессам.
Мне кажется странным, что:
max memory size (kbytes, -m) unlimited
отсутствует в /etc/security/limits.conf, хотя он ограничивает только потребление памяти на процесс, а не в целом для 1 учетной записи пользователя. Вместо того, чтобы добавлять Cgroup, им следовало бы просто изменить существующие команды unix, чтобы приспособить их к этим новым функциям.