LINUX.ORG.RU

setrlimit


0

1

Помогите разобраться с setrlimit.

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

Этот код:

#include <cstdlib>
#include <cstdio>
#include <sys/resource.h>

using namespace std;

int main(int argc, char *argv[])
{
   rlimit limit;
   limit.rlim_cur = 32*1024*1024;   // 32 MB
   limit.rlim_max = RLIM_INFINITY;
   setrlimit(RLIMIT_AS, &limit);

   int counter = 0;
   while(true)
   {
      void* p = malloc(1024*1024);

      if (!p)
         break;

      counter += 1024*1024;
   }

   printf("%d MB allocated\n", counter/1024/1024);

	return EXIT_SUCCESS;
}

возвращает «20 MB allocated».

Не могу понять куда деваются еще 12 MB памяти.



Последнее исправление: Spacer (всего исправлений: 1)

Под маком память все еще выделяется.

andreyu ★★★★★
()

Но если выделенную память проинциализироваить, то уже при выделении 4Гб начинаются тормоза.

Уже 15Гб выделено. Тормозит система, но работает.

Вот почему лимиты не работают не понятно.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

На 17Гб прибил приложение. Отзывчивость системы быстро восстановилась. Это приятно. Под линуксом я бы еще долго наблюдал общение со свопом.
Хоть какой то плюс увидел в макоси.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Вот почему лимиты не работают не понятно.

Макось ничего не знает про RLIMIT_AS:

The resource parameter is one of the following:

     RLIMIT_CORE     The largest size (in bytes) core file that may be created.

     RLIMIT_CPU      The maximum amount of cpu time (in seconds) to be used by each process.

     RLIMIT_DATA     The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the sbrk(2) system call.

     RLIMIT_FSIZE    The largest size (in bytes) file that may be created.

     RLIMIT_MEMLOCK  The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.

     RLIMIT_NOFILE   The maximum number of open files for this process.

     RLIMIT_NPROC    The maximum number of simultaneous processes for this user id.

     RLIMIT_RSS      The maximum size (in bytes) to which a process's resident set size may grow.  This imposes a limit on the amount of physical memory to be given to a process; if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size.

     RLIMIT_STACK    The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended.  Stack extension is performed automatically by the system.

andreyu ★★★★★
()

может использовать strace

strace -odata ./progname
натравить awk на mmap2 и посчитать сколько выделяется.

rg-400
()

Посмотрел под линуксом:
20 MB allocated

andreyu ★★★★★
()
Ответ на: комментарий от Spacer
#include <stdlib.h>
#include <stdio.h>
#include <sys/resource.h>

int
main(int argc, char *argv[])
{
        rlimit limit;
        int counter = 0;

        if (argc < 2)
                return 1;

        limit.rlim_cur = atoi(argv[1])*1024*1024;   // 32 MB
        limit.rlim_max = RLIM_INFINITY;
        setrlimit(RLIMIT_AS, &limit);

        for(;;) {
                void* p = malloc(1024*1024);
                if (!p)
                        break;
                counter += 1024*1024;
        }
        printf("%d", counter/1024/1024);
        return 0;
}
#!/bin/bash
#bash1.sh
progname='test_limit';
source_c='test_limit.c';
data='data';

if [ -z "$1" ]
then
        echo -e $0 [0-9]\*;
        exit 1;
fi;

g++ -o "$progname" "$source_c" 2>/dev/null &&\
strace -o"$data" "./""$progname" "$1" 1>/dev/null &&\
awk  '/mmap2/\
{if ($8 != "-1")
         {a+=$2;}
print a;
}' $data | tail -1

./bash.sh 32
./bash.sh 1
rg-400
()
Ответ на: комментарий от Spacer
int counter = 0;
while(true)
{
void* p = malloc(1024*1024);

if (!p)
break;

counter += 1024*1024;
}

break не отработает только в случае лажи malloc-а. а установленные лимиты вряд ли эту лажу дадут.

ananas ★★★★★
()
Ответ на: комментарий от rg-400

а ответ в этой фразе:

RLIMIT_AS This is the maximum size of a process' total available memory, in bytes.

rg-400
()
Ответ на: комментарий от anonymous

А не наоборот? break выкинет из цикла только в случае p=NULL?!

И как я понял, RLIMIT_AS накладывает ограничения не на объём выделяемой из кучи памяти. Посему RLIMIT_AS - это верхняя грань для malloc, но не супремум.

RLIMIT_AS Максимальный размер виртуальной памяти (адресного пространства) процесса в байтах. Учитывается в вызовах brk(2), mmap(2) и mremap(2), которые завершатся с ошибкой ENOMEM, если будет превышено это ограничение. Также завершится с ошибкой автоматическое расширение стека (и будет сгенерирован сигнал SIGSEGV, по которому завершится процесс, если не было создано с помощью sigaltstack(2) альтернативного стека). Так как значение имеет тип long, на машинах с 32-битным long максимальное значение ограничения будет около 2 ГиБ, или этот ресурс не ограничивается.

, то есть ни слова о куче нет.

backbone ★★★★★
()
Ответ на: комментарий от anonymous

> > break отработает только в случае лажи malloc-а.

selffix


да, это что-то я погорячился. был пьян, прошу простить.тс-у - проверять errno

ananas ★★★★★
()
Ответ на: комментарий от Spacer

Раскопки выхлопа strace показали, что linux отображает в память слинкованные либы (libstdc++, libc, libm, ...), что и занимает искомые 12MB.

Spacer
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.