出于充分的理由,几乎没有内存分配器将块返回给操作系统
内存只能以页为单位从程序中删除,即使这样也不太可能被观察到。
calloc(3) and malloc(3) do interact with the kernel to get memory, if necessary. But very, very few implementations of free(3) ever return memory to the kernel1, they just add it to a free list that calloc() and malloc() will consult later in order to reuse the released blocks. There are good reasons for this design approach.
即使 free() 想要将内存返回给系统,它也需要至少一个连续的内存页才能让内核真正保护该区域,因此释放一小块只会导致保护更改(如果它是)这last页面中的小块。
操作原理
因此 malloc(3) 在需要时从内核获取内存,最终以离散页倍数为单位。这些页面根据程序的需要进行划分或合并。 malloc 和 free 合作维护一个目录。它们在可能的情况下合并相邻的空闲块,以便能够提供大块。目录可能涉及也可能不涉及使用已释放块中的内存来形成链接列表。 (替代方案是更共享内存和分页友好,并且它涉及专门为目录分配内存。)即使特殊和可选的调试代码被编译成,Malloc 和 free 也几乎没有能力强制访问各个块该程序。
1. The fact that very few implementations of free() attempt to return memory to the system is not at all due to the implementors slacking off.
Interacting with the kernel is much slower than simply executing library code, and the benefit would be small. Most programs have a steady-state or increasing memory footprint, so the time spent analyzing the heap looking for returnable memory would be completely wasted. Other reasons include the fact that internal fragmentation makes page-aligned blocks unlikely to exist, and it's likely that returning a block would fragment blocks to either side. Finally, the few programs that do return large amounts of memory are likely to bypass malloc() and simply allocate and free pages anyway.