5 ms·
>There is exactly zero difference from the operating system's perspective (...) Close, but not quite: in case of larger allocations, malloc() tends to use mmap
by dexen 8y ago
>There is exactly zero difference from the operating system's perspective (...)
Close, but not quite: in case of larger allocations, malloc() tends to use mmap( , , , | MAP_ANON) rather than brk() to request memory from the OS. For example, the glibc's malloc() uses mmap() when requested size exceeds MMAP_THRESHOLD, which is 128kB by default.
The mmap() approach gives large, continuous memory blocks that can also be easily free()'d via munmap() with little to no bookkeeping needed[1] - not being subject to the same fragmentation woes as memory allocated via brk() - as long as your address space is significantly larger than allocated memory.
That aside, I fully agree with the author of 9cc.
[1] in fact a simplistic libc memory allocator could directly wrap malloc() around mmap(), free() around munmap() and realloc() around mrealloc(), leveraging the in-kernel allocator at the cost of one syscall with at least two context switches at each call - i.e., slowww
- cperciva 8y agoUsing mmap/munmap isn't quite that trivial: You need to remember how large each allocation is in order to know how many pages to unmap.
- wtracy 8y agoAn implementation certainly could return memory to the OS on calls to free(), but to my knowledge none of the widely used implementations do so. (I would be interested to learn of counterexamples!)
- cperciva 8y agojemalloc can use madvise(MADV_FREE) to return pages to the OS.