Ограничить физическую память на процесс - PullRequest
16 голосов
/ 30 июля 2011

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

Поскольку для своих тестов я не всегда хочу использовать реальные входные данные Я хочу ограничить объем памяти, доступный для моего процесса. Я обнаружил, что могу установить параметр ядра mem, чтобы ограничить физически используемую память всех процессов (верно?)

Есть ли способ сделать то же самое, но с ограничением на процесс . Я видел ulimit, но он ограничивает только виртуальную память на процесс. Любые идеи (может быть, я даже могу установить это программно из моего кода C ++)?

Ответы [ 6 ]

11 голосов
/ 01 августа 2011

Вы можете попробовать с '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 МБ физической + подкачки.

В этом каталоге есть другие настраиваемые параметры, но точный список будет зависеть от используемой вами версии ядра.

Вы даже можете создавать иерархии ограничений, просто создавая подкаталоги.

Группа cgнаследуется, когда вы создаете / exec, поэтому, если вы добавите оболочку, из которой запускается ваша программа, в cgroup, она будет назначена автоматически.

Обратите внимание, что вы можете смонтировать cgroups в любом каталоге, который вам нужен, а не только в /DEV / контрольные группы.

5 голосов
/ 30 июля 2011

Я бы использовал setrlimti с параметром RLIMIT_AS, чтобы установить предел виртуальной памяти (это то, что делает ulimit), а затем попросил бы процесс использовать mlockall (MCL_CURRENT | MCL_FUTURE), чтобы принудительно вызвать ошибку ядра и заблокировать его в физической памяти все страницы процесса, так что виртуальный объем == объем физической памяти для этого процесса

5 голосов
/ 30 июля 2011

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

2 голосов
/ 01 августа 2011

не задумывались ли вы о том, чтобы попробовать свой код в какой-то виртуальной среде? Виртуальная машина может быть слишком много для ваших нужд, но что-то вроде User-Mode Linux может подойти. Это запускает ядро ​​Linux как отдельный процесс в вашей обычной операционной системе. Затем вы можете указать отдельный параметр ядра mem=, а также отдельное пространство подкачки для проведения контролируемых экспериментов.

1 голос
/ 04 августа 2011

Как уже отмечали другие авторы, 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 / C ++. В прошлом я использовал это с хорошим эффектом для контроля пределов размера стека. (Кстати, для ulimit нет выделенной man-страницы, на самом деле это встроенная команда bash, поэтому она находится на man-странице bash.)

1 голос
/ 01 августа 2011

Ядро mem= параметр загрузки ограничивает объем используемой памяти в общей ОС.

Это почти никогда не то, что нужно пользователю.

Для физической памяти существует RSS rlimit aka RLIMIT_AS.

...