Comments 17
Для рядового пользователя была бы полезна такая штука: отслеживаем в реальном времени все процессы, если какой-то из них начинает забирать слишком много памяти (например, более 3 ГБ) в течение короткого времени, ставим такой процесс на паузу (SIGSTOP), а через notification daemon отправляем пользователю уведомление — что делать с таким процессом: прибить или отпустить (SIGCONT). Может неплохо защитить от png-бомбы на 140 гигабайт, просто утечки памяти в GIMP (с ним такое нередко бывает) или просто своей кривой программы, которую программист имел неосторожность запустить на рабочей машине.
+4
UFO just landed and posted this here
Или, знаете ли, просто возьмите systemd.
Он, к тому же, отслеживает дочерние процессы контролируемого. Что будет, если к нашему big_alloc добавить fork и выделять память в нём? Что-то будет работать — qemu, lxc, я полагаю (systemd работает поверх тех же cgroups). Я хотел испытать пару упомянутых методов, но эксперименты автора не воспроизводимы. ptrace-restrict валится на этапе сборки, для lxc наверное надо контейнер создать, LD_PRELOAD не работает на изначальном примере…
$ systemd-run --scope -p MemoryLimit=2M -p MemoryAccounting=yes ./mem
Running as unit run-818.scope.
pp[0] = 0x1473f60
...
pp[511] = 0x465cf50
Killed
Он, к тому же, отслеживает дочерние процессы контролируемого. Что будет, если к нашему big_alloc добавить fork и выделять память в нём? Что-то будет работать — qemu, lxc, я полагаю (systemd работает поверх тех же cgroups). Я хотел испытать пару упомянутых методов, но эксперименты автора не воспроизводимы. ptrace-restrict валится на этапе сборки, для lxc наверное надо контейнер создать, LD_PRELOAD не работает на изначальном примере…
-1
Так а разве systemd-run не запустит программу под теми же cgroups? В чём тогда отличие от lxc в данном случае кроме управления через systemd и удобства?
0
Именно так, я это упомянул. На мой взгляд, удобства — достаточный аргумент для использования. В статье почему-то используется пример lxc-macvlan.conf, в котором создаётся сеть. Зачем она для ограничения памяти — непонятно. Можно было его урезать до задания utsname и добавить нужные лимиты.
Хм, и не понял, за что тут наминусовали. Кто-то воспроизвёл все эксперименты без проблем?
Хм, и не понял, за что тут наминусовали. Кто-то воспроизвёл все эксперименты без проблем?
Скрытый текст
$ make ptrace-restrict
gcc -g ptrace-restrict.c -o ptrace-restrict
ptrace-restrict.c: In function ‘handle_brk’:
ptrace-restrict.c:55:32: error: ‘struct user_regs_struct’ has no member named ‘ebx’
dbg("brk addr 0x%08X\n", state.ebx);
^
ptrace-restrict.c:19:18: note: in definition of macro ‘dbg’
make big_alloc_linker
gcc -g big_alloc.c -o big_alloc_linker -Wl,-T hack.lst
gcc-4.9.real: error: hack.lst: No such file or directory
+1
В Windows можно было отдельную кучу для этой задачи создать и только ее использовать.
0
А статья о самом решении задачи сортировки будет?
+1
А вам известны решения задачи не только ограничивать память, но еще и ее сегментировать, чтобы, например, доступно было много, но выделить кусок более 64 килобайт было нельзя? У меня недавно возникла задача отладки алгоритма в условиях сегментации памяти, он падал если приложение работало долгое время. Мое решение было слишком примитивное — перед стартом алгоритма выделить много маленьких кусочков, потом через один-два освобождать.
0
Чтобы ограничить ресурсы с помощью cgroup не обязательно заводить отдельное окружение (lxc-контейнер). Достаточно завести свою группу, выставить ей нужные лимиты и приписать свой процесс туда. Пример:
$ cgcreate -g memory:/myGroup
$ echo $(( 500 * 1024 * 1024 )) > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
$ echo $(( 5000 * 1024 * 1024 )) > /sys/fs/cgroup/memory/myGroup/memory.memsw.limit_in_bytes
$ cgexec -g memory:myGroup myProgramm
Утилиты для работы входят в пакет libcgroup-tools (для CentOS). При желании таким же макаром можно прописать ограничения для системных пользователей или групп.
Собственно контейнера lxc по такому принципу и работают.
$ cgcreate -g memory:/myGroup
$ echo $(( 500 * 1024 * 1024 )) > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
$ echo $(( 5000 * 1024 * 1024 )) > /sys/fs/cgroup/memory/myGroup/memory.memsw.limit_in_bytes
$ cgexec -g memory:myGroup myProgramm
Утилиты для работы входят в пакет libcgroup-tools (для CentOS). При желании таким же макаром можно прописать ограничения для системных пользователей или групп.
Собственно контейнера lxc по такому принципу и работают.
0
Круто, я пытался сделать что-то подобное, но не смог, поэтому заюзал lxc-контейнер. По cgroups очень сложно найти какую-то внятную документацию, чтобы человек извне мог понять что вообще происходит — к чему там все эти иерархии, контроллеры и пр. и как оно, собственно, работает. Может вы напишите кратенькую статейку-ликбез на эту тему?
0
По-моему сильно проще использовать malloc_usable_size() для определения размера выделенного блока. Это и будет правильный размер блока, а не то, сколько мы запрашивали. Код будет в разы проще и не нужно будет никакого хэша снаружи.
0
Sign up to leave a comment.
Ограничение памяти, доступной программе