Does malloc() use brk() or mmap()?
Solution 1
If we change the program to see where the malloc
'd memory is:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void program_break_test() {
printf("%10p\n", sbrk(0));
char *bl = malloc(1024 * 1024);
printf("%10p\n", sbrk(0));
printf("malloc'd at: %10p\n", bl);
free(bl);
printf("%10p\n", sbrk(0));
}
int main(int argc, char **argv) {
program_break_test();
return 0;
}
It's perhaps a bit clearer that sbrk
wouldn't change. The memory given to us by malloc
is being mapped into a wildly different location.
You could also use strace
on Linux to see what system calls are made, and find out that malloc
is using mmap
to perform the allocation.
Solution 2
malloc
is not limited to using sbrk
to allocate memory. It might, for example, use mmap
to map a large MAP_ANONYMOUS
block of memory; normally mmap
will assign a virtual address well away from the data segment.
There are other possibilities, too. In particular, malloc
, being a core part of the standard library, is not itself limited to standard library functions; it can make use of operating-system-specific interfaces.
Solution 3
If you use malloc
in your code, it will call brk()
at the beginning, allocated 0x21000 bytes from the heap, that's the address you printed, so the Question 1: the following malloc
s requirements can be meet from the pre-allocated space, so these mallocs actually didn't call brk
, it is a optimization in malloc
. If next time you want to malloc size beyond that boundary, a new brk
will be called (if not large than the mmap
threshold).
Eric
while(fail) { pivot(); trial(); } while(succeed) { repeat(); improve(); }
Updated on June 01, 2022Comments
-
Eric almost 2 years
c code:
// program break mechanism // TLPI exercise 7-1 #include <stdio.h> #include <stdlib.h> void program_break_test() { printf("%10p\n", sbrk(0)); char *bl = malloc(1024 * 1024); printf("%x\n", sbrk(0)); free(bl); printf("%x\n", sbrk(0)); } int main(int argc, char **argv) { program_break_test(); return 0; }
When compiling following code:
printf("%10p\n", sbrk(0));
I get warning tip:
format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int’
Question 1: Why is that?
And after I
malloc(1024 * 1024)
, it seems the program break didn't change.Here is the output:
9b12000 9b12000 9b12000
Question 2: Does the process allocate memory on heap when start for future use? Or the compiler change the time point to allocate? Otherwise, why?
[update] Summary: brk() or mmap()
After reviewing TLPI and check man page (with help from author of TLPI), now I understand how
malloc()
decide to usebrk()
ormmap()
, as following:mallopt()
could set parameters to control behavior ofmalloc()
, and there is a parameter namedM_MMAP_THRESHOLD
, in general:- If requested memory is less than it,
brk()
will be used; - If requested memory is larger than or equals to it,
mmap()
will be used;
The default value of the parameter is
128kb
(on my system), but in my testing program I used 1Mb, sommap()
was chosen, when I changed requested memory to 32kb, I sawbrk()
would be used.The book mentioned that in TLPI page 147 and 1035, but I didn't read carefully of that part.
Detailed info of the parameter could be found in man page for
mallopt()
. - If requested memory is less than it,