Показать статистику
+1 голос
от (4.6тыс. баллов)
Вопрос скорее теоретический. Возникла мысль немного оптимизировать использование ресурсов на своей VPS-ке. После небольшого анализа обнаружил что некоторые процессы потребляют слишком много. Я понимаю что ограничение использования памяти может привести к печальным последствиям (эти процессы могут умереть), но тем не менее хочу узнать - как ограничить память для процесса в Линукс?
4.9тыс. просмотров 1 ответов

1 Ответ

0 голосов
от (17.4тыс. баллов)

Одним из способов ограничения памяти для процесса, запускаемого в шеле (bash, sh) является утилита ulimit. Можно использовать ulimit с ключем -v:

ulimit -v

Такой ключ ограничивает количество памяти, доступной процессу. Если приложение требует больше памяти для корреткной работы, а ulimit эту программу ограничивает, скорее всего процесс умрет (завершится abort). 

Есть по крайней мере два варианта 

Первый, мы уже фактически рассмотрели - это ограничение памяти процессу ulimit -v.

Второй вариант - если запускаемая программа рекурсивно обращается к различным библиотекам или другим процессам. В таком случае нужно контролировать размер стека через ключ -s 

ulimit -s

Команда ulimit использует "жесткие" (hard) и так называемые софт (soft) лимиты. Хард лимиты могут быть только уменьшены, увеличить использование ресурсов по жесткому лимиту нельзя. Лично я не рекомендовал бы менят значения хард лимитов, а использовать софт лимиты. Что бы задать значения софт лимитов, ulimit можно использовать так:

ulimit -Sv

Если нужно только посмотреть текущие значения:

ulimit -Sa

Вывод на обычном сервере с Ubuntu:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) 1024
pending signals                 (-i) 31030
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
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) 31030
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

В сети еще есть интересный скрипт на Perl для ограничения памяти: http://coldattic.info/page/resourcelimit/

Для старых версий Linux (не помню точно с какой версии ядра ключ -m перестал работать), можно контролировать размер "резидентной" памяти:

ulimit -t 300s -m 100000k your_program ...

В примере выше для программы "your_program" задается ограничение по времени выполнения (300 милисекнд) и 100 тысяч килобайт памяти. Как только программа выйдет за разрешенные лимиты, стандартный вывод ошибок STDERR сообщит о проблеме и программа завершится.

Есть альтернативный метод - использовать cgroups:

cgcreate -g memory:/my_group
echo $(( 100 * 1024 * 1024 )) > /sys/fs/cgroup/memory/my_group/memory.limit_in_bytes
echo $(( 1000 * 1024 * 1024 )) > /sys/fs/cgroup/memory/my_group/memory.memsw.limit_in_bytes

Я думаю из приведенного выше примера уже интуитивно понятно что задано и что сделано. Тем не менее, поясню. Мы создали специальную группу с названием "my_group" и ограничили ресурсы (память) для любых процессов, запускаемвых в этой группе. В данном случае мы поставили ограничение в 100 мебагайт физической памяти и 1000 мегабайт в pagefile (файл подкачки, он же swap).

Как запустить приложение your_program в группе my_group:

cgexec -g memory:my_group your_program

Что бы пользоваться cgroups на Debian или Ubuntu, нужно предварительно устанеовить пакет:

apt install cgroup-bin

И иак же нужно отредавтировать конфигурацию загрузчика (в данном примере - grub):

vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"

Далее сохранить конфиг и обноить конфигурацию загрузчика:

sudo update-grub
...