Suppose a request handler needs memory for a small object:
malloc() often returns a pointer without entering the kernel. That is because it manages memory in user space.
The allocator first obtains larger memory regions from the operating system. It then splits those regions into smaller blocks, tracks which ones are free, and reuses them for future allocations.
Most malloc() calls are handled entirely by the allocator. The kernel is involved only when more memory is needed or when a suitable region can be returned.
malloc()is usually a user-space memory allocator, not a system call for every allocation.
This explains why allocation is fast, why free() does not need a size argument, and why freeing memory does not always reduce a process’s memory footprint.
This chapter follows allocations through arenas, chunks, bins, splitting, and coalescing, explains how allocators obtain and return memory to the operating system, and examines alignment, fragmentation, concurrency, failure, and corruption.