I'm new to C and heap memory, still struggling to understand dynamic memory allocation.
I traced Linux system calls and found that if I use malloc
to request a small amount of heap memory, then malloc
calls brk
internally.
But if I use malloc
to request a very large amount of heap memory, then malloc
calls mmap
internally.
So there must be a big difference between brk
and mmap
, but theoretically we should be able to use brk
to allocate heap memory regardless of the requested size. So why does malloc
call mmap
when allocating a large amount of memory?
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 .
For very large requests, malloc() uses the mmap() system call to find addressable memory space. This process helps reduce the negative effects of memory fragmentation when large blocks of memory are freed but locked by smaller, more recently allocated blocks lying between them and the end of the allocated space.
Malloc generally functions in most of the memory management process. In the event the program requires additional memory, this is borrowed from the OS. Mmap on the other hand makes use of a context switch that converts into kernel land.
Almost always, memory is much faster than disk, and malloc is not what's costing time. The mmap code is faster because for your program, mmap has resulted in either less disk access, or more efficient disk access, than whatever reads and writes you compared against.
so why malloc calls mmap when it comes to allocate a large size of memory?
The short answer is for improved efficiency on newer implementations of Linux, and the updated memory allocation algorithms that come with them. But keep in mind that this is a very implementation dependent topic, and the whys and wherefores would vary greatly for differing vintages and flavors of the specific Linux OS being discussed.
Here is fairly recent write-up regarding the low-level parts mmap()
and brk()
play in Linux memory allocation. And, a not so recent, but still relevant Linux Journal article that includes some content that is very on-point for the topic here, including this:
For very large requests, malloc() uses the mmap() system call to find addressable memory space. This process helps reduce the negative effects of memory fragmentation when large blocks of memory are freed but locked by smaller, more recently allocated blocks lying between them and the end of the allocated space. In this case, in fact, had the block been allocated with brk(), it would have remained unusable by the system even if the process freed it.
(emphasis mine)
Regarding brk()
:
incidentally, "...mmap() didn't exist in the early versions of Unix. brk()
was the only way to increase the size of the data segment of the process at that time. The first version of Unix with mmap() was SunOS in the mid 80's, the first open-source version was BSD-Reno in 1990.". Since that time, modern implementation of memory allocation algorithms have been refactored with many improvements, greatly reducing the need for them to include using brk()
.
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