I'm experimenting with a simple C program that keeps allocating memory:
for ( i = 0; i < 10000; i ++ )
{
array[i] = malloc( 1024*1024 );
if ( array[i] == NULL )
{
break;
}
printf("Sleeping...%d\n", i);
sleep( 60 );
}
Full code pasted here: http://tny.cz/2d9cb3df
However, when I cat /proc/pid/maps
, I get no [heap]
section. Why?
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]
The /proc/[pid]/mem file and Virtual Memory In short, the /proc/[pid]/maps file provides us the address; the /proc/[pid]/mem provides an interface into the memory space holding our data.
In linux, /proc includes a directory for each running process, including kernel processes, in directories named /proc/PID, these are the directories present: directory. description. /proc/PID/cmdline. Command line arguments.
/proc/[pid]/statm Provides information about memory usage, measured in pages.
Function proc_self::exe[−][src]Returns a File of the currently running executable. Akin to fd::File::open("/proc/self/exe") on Linux.
Since you're talking about /proc/pid/maps
I assume you're on linux.
This is what man malloc
tells me on the linux distribution I happen to run:
Normally,
malloc()
allocates memory from the heap, and adjusts the size of the heap as required, usingsbrk(2)
.When allocating blocks of memory larger than
MMAP_THRESHOLD
bytes, the glibcmalloc()
implementation allocates the memory as a private anonymous mapping usingmmap(2)
.MMAP_THRESHOLD
is 128 kB by default, but is adjustable usingmallopt(3)
.Allocations performed using
mmap(2)
are unaffected by theRLIMIT_DATA
resource limit (seegetrlimit(2)
).
If you really want to see [heap]
in your /proc/pid/maps
allocate less than 128k per call to malloc.
The said section is just not declared as "heap", as it is allocated via mmap()
calls.
Here on my 64 bit system, the memory allocated comes from this constantly growing section:
7f7fbda7a000-7f7fbdc7c000 rw-p 00000000 00:00 0
...
7f7fbc868000-7f7fbdc7c000 rw-p 00000000 00:00 0
...
7f7fbc363000-7f7fbdc7c000 rw-p 00000000 00:00 0
The section is extended at the start and the newly allocated memory always ias the start address + 0x10.
What the memory allocator does here is
mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7fbb353000
Strange thing; I would have suspected that every mmap()
ed memory section is shown separately. But if I have the program do intermediate free()
calls, the memory allocation follows this:
7f16be944000-7f16bec47000 rw-p 00000000 00:00 0
7f16bed48000-7f16bee49000 rw-p 00000000 00:00 0
There has been made a hole in the otherwise contiguous memory.
And an additional thing happens: in this modified program, there is indeed a [heap]
section. Due to reasuns beyond my understanding, the program swithces over to allocating via brk()
, and this is (probably) where the heap comes from:
with every brk()
call, the respective section is extended at its end:
01183000-029a4000 rw-p 00000000 00:00 0 [heap]
I do not know what has changed malloc()
's mind to take the "real" heap (the stuff connected to brk()
) for the allocations. The first munmap()
call, related to a respective free()
, seems to produce this.
According to this, there seems to be a maximum for mmap()
ed chunks. If this is exceeded, gnulibc falls back to brk()
/sbrk()
, which operates on the "regular heap area".
So, shorter answer: The malloc()
ed memory taken from via brk()
is on the "real" [heap]
section, the mmap()
ed memory sections are not tagged as [heap]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With