Ограничение физической памяти на процесс
Я пишу алгоритм для выполнения некоторых внешних вычислений памяти, т.е. когда ваши входные данные не вписываются в основную память, и вам приходится учитывать сложность ввода/вывода.
Так как для моих тестов я не всегда хочу использовать реальные входы, я хочу ограничить объем памяти, доступный для моего процесса. Я нашел, что я могу установить параметр ядра mem
для ограничения физически используемой памяти всех процессов (это верно?)
Есть ли способ сделать то же самое, но с лимитом на процесс. Я видел ulimit
, но он ограничивает только виртуальную память для каждого процесса. Любые идеи (возможно, я могу даже установить его программно из моего кода на С++)?
Ответы
Ответ 1
Вы можете попробовать с 'cgroups'.
Для их использования введите следующие команды: root.
# mkdir /dev/cgroups
# mount -t cgroup -omemory memory /dev/cgroups
# mkdir /dev/cgroups/test
# echo 10000000 > /dev/cgroups/test/memory.limit_in_bytes
# echo 12000000 > /dev/cgroups/test/memory.memsw.limit_in_bytes
# echo <PID> > /dev/cgroups/test/tasks
Где PID процесса, который вы хотите добавить в группу. Обратите внимание, что предел применяется к сумме всех процессов, назначенных этой группе.
С этого момента процессы ограничены 10 МБ физической памяти и 12 Мбайт pysical + swap.
В этом каталоге есть другие настраиваемые параметры, но точный список будет зависеть от используемой версии ядра.
Вы даже можете создавать иерархии ограничений, просто создавая подкаталоги.
Сгруппа наследуется, когда вы fork/exec, поэтому, если вы добавите оболочку из вашей программы, запущенной в группу, она будет назначена автоматически.
Обратите внимание, что вы можете монтировать группы в любой каталог, который вы хотите, а не только/dev/cgroups.
Ответ 2
Я не могу предоставить прямой ответ, но, как правило, пишу свою собственную систему управления памятью, чтобы я мог полностью контролировать область памяти и сколько я выделяю. Это обычно применяется, когда вы пишете для микроконтроллеров. Надеюсь, что это поможет.
Ответ 3
Я бы использовал setrlimti с параметром RLIMIT_AS, чтобы установить предел виртуальной памяти (это то, что делает ulimit), а затем использовать процесс mlockall (MCL_CURRENT | MCL_FUTURE), чтобы заставить ядро сбой и заблокировать его в физическом ОЗУ все страницы процесса, так что количество виртуальных == количество физической памяти для этого процесса
Ответ 4
Вы считали, что пытаетесь использовать свой код в какой-то виртуальной среде? Виртуальная машина может быть слишком большой для ваших нужд, но что-то вроде User-Mode Linux может быть хорошей подгонкой. Это запускает ядро Linux как единый процесс внутри вашей обычной операционной системы. Затем вы можете предоставить отдельный параметр ядра mem=
, а также отдельное пространство подкачки для проведения контролируемых экспериментов.
Ответ 5
Kernel mem=
параметр загрузки ограничивает количество памяти в общей операционной системе.
Это почти никогда не требуется пользователю.
Для физической памяти существует RSS rlimit aka RLIMIT_AS
.
Ответ 6
Как уже отмечали другие плакаты, setrlimit является наиболее вероятным решением, оно контролирует пределы всех настраиваемых аспектов среды процесса. Используйте эту команду для просмотра этих отдельных параметров в процессе работы оболочки:
ulimit -a
Ниже перечислены наиболее важные для вашего сценария результаты:
data seg size (kbytes, -d) unlimited
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
virtual memory (kbytes, -v) unlimited
Оформить страницу руководства для setrlimit ( "man setrlimit" ), ее можно вызывать программно из вашего кода C/С++. Я использовал его для хорошего эффекта в прошлом для контроля ограничений размера стека. (Кстати, для ulimit нет специальной справочной страницы, на самом деле это встроенная команда bash, поэтому она находится на странице bash man.)