2013-07-22 3 views
7

Я экспериментировал с простой программой C, которая держит выделяющий память:отсутствует [куча] раздел в/Proc/PID/карты

for (i = 0; i < 10000; i ++) 
{ 
    array[i] = malloc(1024*1024); 
    if (array[i] == NULL) 
    { 
     break; 
    } 
    printf("Sleeping...%d\n", i); 
    sleep(60); 
} 

Полный код вставили здесь: http://tny.cz/2d9cb3df

Однако, когда я cat /proc/pid/maps, я не получаю [heap] раздел. Зачем?

08048000-08049000 r-xp 00000000 08:11 17   /data/a.out 
08049000-0804a000 r--p 00000000 08:11 17   /data/a.out 
0804a000-0804b000 rw-p 00001000 08:11 17   /data/a.out 
0804b000-0805e000 rw-p 00000000 00:00 0 
b74c6000-b75c8000 rw-p 00000000 00:00 0 
b75c8000-b7775000 r-xp 00000000 08:01 3539272 /lib/i386-linux-gnu/libc-2.17.so 
b7775000-b7777000 r--p 001ad000 08:01 3539272 /lib/i386-linux-gnu/libc-2.17.so 
b7777000-b7778000 rw-p 001af000 08:01 3539272 /lib/i386-linux-gnu/libc-2.17.so 
b7778000-b777b000 rw-p 00000000 00:00 0 
b7797000-b779a000 rw-p 00000000 00:00 0 
b779a000-b779b000 r-xp 00000000 00:00 0   [vdso] 
b779b000-b77bb000 r-xp 00000000 08:01 3539289 /lib/i386-linux-gnu/ld-2.17.so 
b77bb000-b77bc000 r--p 0001f000 08:01 3539289 /lib/i386-linux-gnu/ld-2.17.so 
b77bc000-b77bd000 rw-p 00020000 08:01 3539289 /lib/i386-linux-gnu/ld-2.17.so 
bff21000-bff42000 rw-p 00000000 00:00 0   [stack] 
+0

Compi ler выводит, что цикл for ничего не делает (т.е. е. no-op) и оптимизирует его? –

+0

образованное предположение? –

+0

@ H2CO3, я изменил его, чтобы распечатать выделенный адрес, и он все тот же. – lang2

ответ

4

Поскольку вы говорите о /proc/pid/maps Я предполагаю, что вы на Linux.

Это то, что man malloc говорит мне о распределении Linux Я случиться, чтобы запустить:

Обычно, malloc() выделяет память из кучи, и регулирует размер кучи по мере необходимости, с помощью sbrk(2).

При распределении блоков памяти, превышающих MMAP_THRESHOLD байт, реализация glibc malloc() выделяет память как личное анонимное сопоставление с использованием mmap(2). MMAP_THRESHOLD по умолчанию 128 kB, но настраивается с использованием mallopt(3).

Ассигнования, полученные с использованием mmap(2), не зависят от предела ресурса RLIMIT_DATA (см. getrlimit(2)).

Если вы действительно хотите увидеть [heap] в вашем /proc/pid/maps выделить менее 128k за звонок в таНос.

1

Упомянутый раздел просто не объявлен как «куче», так как она выделяется через mmap() вызовов.

Здесь на моей 64 битной системе, память, выделяемая исходит от этого постоянно растущего раздела:

7f7fbda7a000-7f7fbdc7c000 rw-p 00000000 00:00 0 
... 
7f7fbc868000-7f7fbdc7c000 rw-p 00000000 00:00 0 
... 
7f7fbc363000-7f7fbdc7c000 rw-p 00000000 00:00 0 

Раздел продолжается на старте и вновь выделенная память всегда IAS начальный адрес + 0x10.

Что распределяющий память делает здесь

mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7fbb353000 

Странная вещь; Я бы предположил, что каждая секция памяти mmap() показана отдельно. Но если у меня есть программа делать промежуточные free() звонки, распределение памяти следующим образом:

7f16be944000-7f16bec47000 rw-p 00000000 00:00 0 
7f16bed48000-7f16bee49000 rw-p 00000000 00:00 0 

Там было сделано отверстие в противном случае непрерывной памяти.

И еще одна вещь: в этой модифицированной программе действительно есть раздел [heap]. Благодаря reasuns за пределами моего понимания, программа swithces к распределению через brk(), и это (возможно), где куча приходит от:

с каждым brk() вызова, соответствующий раздел распространяются на его конце:

01183000-029a4000 rw-p 00000000 00:00 0         [heap] 

Я не знаю, что изменило сознание, чтобы взять «настоящую» кучу (материал, связанный с brk()) для распределений. Первый вызов munmap(), связанный с соответствующим free(), кажется, создает это.

Согласно this, существует, по-видимому, максимум для mmap() редких кусков. Если это превышено, gnulibc возвращается к brk()/sbrk(), который работает в «обычной области кучи».

Итак, короче ответ: malloc() редактора память взят из через brk() на «реальный» [heap] раздел, mmap() секции изда памяти не помечена как [heap].

0

Динамические распределения производятся с использованием вызова brk(). Начало раздела .brk рассчитывается во время загрузки программы (посмотрите на load_elf_binary() в /linux/fs/binfmt_elf.c). Тем не менее, страница не отображается до во время выполнения, когда запрашивается фактическое распределение. Ниже экрана шоу из/Proc/PID/карты до и после размещения на системе x86_64

перед вызовом calloc (8032,1):

$ cat /proc/$(pid)/maps 

00400000-00401000 r-xp 00000000 08:02 1314308    /testheap 

00600000-00601000 r--p 00000000 08:02 1314308    /testheap 

00601000-00602000 rw-p 00001000 08:02 1314308    /testheap 

7fafeea3e000-7fafeebfb000 r-xp 00000000 08:02 198420  /lib/x86_64-linux-gnu/libc-2.17.so 

7fafeebfb000-7fafeedfb000 ---p 001bd000 08:02 198420  /lib/x86_64-linux-gnu/libc-2.17.so 

После Вызов calloc (8032,1):

$cat /proc/$(pid)/maps 

00400000-00401000 r-xp 00000000 08:02 1314308    /testheap 

00600000-00601000 r--p 00000000 08:02 1314308    /testheap 

00601000-00602000 rw-p 00001000 08:02 1314308    /testheap 

**021ea000-0220c000 rw-p 00000000 00:00 0     [heap]** 

7fafeea3e000-7fafeebfb000 r-xp 00000000 08:02 198420  /lib/x86_64-linux-gnu/libc-2.17.so 

7fafeebfb000-7fafeedfb000 ---p 001bd000 08:02 198420  /lib/x86_64-linux-gnu/libc-2.17.so 

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