Missing [heap] section in / proc / pid / maps

I am experimenting with a simple C program that saves memory allocation:

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 inserted here: http://tny.cz/2d9cb3df

However, when I cat /proc/pid/maps , I do not get the [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] 
+7
c memory
source share
3 answers

Since you are talking about /proc/pid/maps , I assume you are on Linux.

This is what man malloc tells me about the Linux distribution that I ran:

Normally malloc() allocates memory from the heap and adjusts the heap size if necessary using sbrk(2) .

When allocating memory blocks exceeding MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates memory as a personal anonymous mapping using mmap(2) . MMAP_THRESHOLD is 128 kB by default, but is configured using mallopt(3) .

Resource allocation using mmap(2) is independent of the resource limit of RLIMIT_DATA (see getrlimit(2) ).

If you really want to see [heap] in your /proc/pid/maps , allocate less than 128k per call in malloc.

+4
source share

The specified section is simply not declared as a heap because it is allocated through mmap() calls.

Here, on my 64-bit system, the allocated memory comes from this ever-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 partition expands at the beginning, and the newly allocated memory always has a starting address + 0x10.

What allocates a memory allocator

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

Strange thing; I would suggest that each section of mmap() ed memory is shown separately. But if I have a program that makes intermediate calls to free() , memory allocation follows this:

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

There was a hole in the continuous memory.

And one more thing: in this modified program there really is a [heap] section. Due to new features, outside of my understanding, the program moves to distribution via brk() , and this is (possibly) where the heap comes from:

with each call to brk() , the corresponding section expands at the end:

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

I do not know what malloc() has changed the mind to take the β€œreal” heap (material related to brk() ) for distributions. The first munmap() call associated with the corresponding free() seems to create this.

According to this , for mmap() ed chunks seems to be the maximum. If this is exceeded, gnulibc returns to brk() / sbrk() , which works in the "normal heap area".

So, the answer is shorter: the malloc() memory taken from brk() is located in the "real" [heap] section, the mmap() ed memory sections are not marked as [heap] .

+1
source share

Dynamic allocations are performed using the brk() call. The beginning of the .brk section is calculated at boot time (look at load_elf_binary () in / linux / fs / binfmt _elf.c). However, the page is not displayed until at run time when the actual distribution is requested. See the below screen view of / proc / pid / maps before and after placement on the x86_64 system.

Before calling 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 

After calling 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 

0
source share

All Articles