2011-07-30 3 views
15

Я пишу алгоритм для выполнения некоторых вычислений внешней памяти, т. Е. Когда ваши входные данные не вписываются в основную память, и вам приходится учитывать сложность ввода-вывода.Ограничение физической памяти на процесс

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

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

+0

Вы полагаетесь на виртуальную память и подкачку linux для загрузки соответствующих данных в память или вы планируете вручную загружать данные вручную в буферы? –

+0

Я использую подкачку виртуальной памяти + linux (плюс библиотека под названием stxxl для некоторых структур данных внешней памяти, но я уже могу контролировать их использование в памяти). – dcn

+1

Добавлен тег linux-kernel, потому что вам, вероятно, нужно напрямую поговорить с ядром для этого , и ребята ядра, скорее всего, узнают об этом. –

ответ

11

Вы можете попробовать: '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.

+0

I должен убедиться в том, что ограничения выполняются с использованием '/ proc//status' и записи' VmHWM', правильно? – dcn

+0

Я не уверен, что это так просто. Сравнивая статус/proc//с группами/*/memory.usage_in_bytes, они несколько отличаются. Возможно, это связано с разделяемой памятью или виртуальной или физической памятью ... Я думаю, что группы ограничивают только новую память, запрошенную процессом, но разделяемая память, существовавшая до того, как процесс добавляется в группу, не учитывается. См. Документы [здесь] (http://www.kernel.org/doc/Documentation/cgroups/memory.txt). – rodrigo

+0

Принимая этот ответ: cgroups работали для меня. Является ли '-ememory' опечаткой (без пробела)? В любом случае мне было удобнее настроить cgconfig соответственно и начать мой процесс непосредственно в cgroup (cgexec), например, здесь, например, http://jlebar.com/2011/6/15/Limiting_the_amount_of_RAM_a_program_can_use.html – dcn

5

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

+1

+1 для простого подхода просто отслеживать использование собственной памяти. –

5

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

+0

'mlockall' действительно проблематично. За исключением того факта, что в некоторых случаях вы действительно хотите ограничить физическую память и наслаждаться обменом (например, настольным приложением), некоторые языки программирования (например, golang или java) выделяют огромное количество виртуального пространства с помощью mmap + PROTO_ANON, поэтому вы не могут их использовать. И даже если вы используете C++, вы не сможете использовать такие вещи, как asan. –

+0

(просто заметьте, я действительно знаю парня, который дал ответ, маленький мир ...) –

1

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

Это почти никогда не требуется пользователю.

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

+0

Вы имеете в виду RLIMIT_RSS? – dcn

+1

Док говорит о RLIMIT_RSS «Этот предел только имеет эффект в Linux 2.4.x, x <30" ... – dcn

+1

Ugh, фактически для каждого процесса rlimit для физической памяти называется «памятью cgroup», иначе более или менее ничего не гарантируется. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=Documentation/cgroups/memory.txt;h=6f3c598971fc3ef05d2ebfb0e6e8879b3047d839;hb=HEAD – adobriyan

2

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

1

Как уже отмечали другие плакаты, 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 

Checkout страница справочника для setrlimit (» man setrlimit "), его можно вызывать программно из вашего кода C/C++. Я использовал его для хорошего эффекта в прошлом для контроля ограничений размера стека. (Кстати, для ulimit нет выделенной справочной страницы, на самом деле это встроенная команда bash, поэтому она находится на странице bash man.)

Смежные вопросы