2013-07-22 11 views
7

sto sperimentando con un semplice programma C che mantiene la memoria allocazione:manca [mucchio] sezione/proc/PID/mappe

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

codice completo incollato qui: http://tny.cz/2d9cb3df

Tuttavia, quando ho cat /proc/pid/maps, non ho la sezione [heap]. Perché?

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

Il compi si deduce che il ciclo for non fa nulla (i. e. no-op) e lo ottimizza? –

+0

un'ipotesi educata? –

+0

@ H2CO3, l'ho modificato per stampare l'indirizzo assegnato ed è sempre lo stesso. – lang2

risposta

4

Dato che stai parlando di /proc/pid/maps presumo che tu sia su linux.

Questo è ciò che mi dice man malloc sulla distribuzione linux mi capita di correre:

Normalmente, malloc() alloca la memoria dal mucchio, e regola la dimensione del mucchio, come richiesto, utilizzando sbrk(2).

Quando si assegnano blocchi di memoria superiori a MMAP_THRESHOLD byte, l'implementazione di glibc malloc() alloca la memoria come mapping anonimo privato utilizzando mmap(2). MMAP_THRESHOLD è di 128 kB per impostazione predefinita, ma è regolabile utilizzando mallopt(3).

Le allocazioni eseguite utilizzando mmap(2) non sono interessate dal limite di risorse RLIMIT_DATA (vedere getrlimit(2)).

Se si vuole veramente vedere [heap] nella vostra /proc/pid/maps allocare meno di 128k per ogni chiamata a malloc.

1

La detta sezione non è solo dichiarata come "cumulo", in quanto è assegnato tramite mmap() chiamate.

Qui sul mio sistema a 64 bit, la memoria allocata viene da questa sezione in costante crescita:

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

La sezione è esteso alla partenza e la memoria appena allocata sempre ias l'indirizzo iniziale + 0x10.

Che l'allocatore di memoria fa qui è

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

Cosa strana; Avrei sospettato che ogni sezione della memoria mmap() ed è mostrata separatamente. Ma se devo fare il programma free() scali intermedi, l'allocazione di memoria segue questo:

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

C'è stato fatto un buco nella memoria altrimenti contigua.

E una cosa aggiuntiva succede: in questo programma modificato, c'è davvero una sezione [heap]. A causa reasuns oltre la mia comprensione, il programma swithces oltre ad assegnare tramite brk(), e questo è (probabilmente) in cui l'heap viene da:

con ogni brk() chiamata, la relativa sezione è esteso al suo termine:

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

Non so cosa è cambiato nella mente di malloc() per prendere l'heap "reale" (le cose connesse a brk()) per le allocazioni. La prima chiamata munmap(), relativa a un rispettivo free(), sembra produrre questo.

Secondo this, sembra esserci un massimo per mmap() ed blocchi. Se questo viene superato, gnulibc torna a brk()/sbrk(), che opera nell'area "heap normale".

Quindi, la risposta più breve: La memoria malloc() Ed tratto da via brk() è il "vero" [heap] sezione, le sezioni di memoria ed mmap() non vengono contrassegnati come [heap].

0

Le allocazioni dinamiche vengono effettuate utilizzando la chiamata brk(). L'inizio della sezione .brk viene calcolato durante il caricamento del programma (guarda load_elf_binary() in /linux/fs/binfmt_elf.c). Tuttavia, una pagina non viene mappata fino a quando durante il runtime viene richiesta l'allocazione effettiva. Vedi sotto uno schermo spettacolo di/proc/PID/mappe prima e dopo un'allocazione su un sistema x86_64

Prima di invocare un 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 

Dopo invocando un 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