Ограничение физической памяти на процесс

Я пишу алгоритм для выполнения некоторых внешних вычислений памяти, т.е. когда ваши входные данные не вписываются в основную память, и вам приходится учитывать сложность ввода/вывода.

Так как для моих тестов я не всегда хочу использовать реальные входы, я хочу ограничить объем памяти, доступный для моего процесса. Я нашел, что я могу установить параметр ядра 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.)