为何我的free()会归还内存给OS,与Stack Overflow案例相反?
为什么free()在你的测试中归还内存给系统,而旧提问中没有?
内存分配机制的核心差异:brk vs mmap
glibc的malloc实现会根据申请内存的大小选择两种截然不同的分配策略:- 对于小块内存(默认阈值通常在128KB左右,不同版本有调整),会通过
brk系统调用扩展进程的堆空间。调用free后,这些内存不会立刻归还给操作系统,而是被glibc内存管理器缓存起来,留待后续malloc请求复用,所以进程的内存占用不会立刻下降。 - 对于大块内存(超过MMAP_THRESHOLD阈值),会直接调用
mmap系统申请匿名内存映射。当你调用free时,glibc会直接调用munmap把这块内存还给操作系统,这就是你在htop中看到内存占用明显下降的原因。
- 对于小块内存(默认阈值通常在128KB左右,不同版本有调整),会通过
glibc版本的策略迭代
你使用的是glibc 2.31,而2018年的提问基于更早的glibc版本。在后续的版本迭代中,glibc优化了大块内存的回收逻辑,比如调整了MMAP_THRESHOLD的默认值,或者增强了内存归还给系统的触发条件,确保超大内存块被释放后能立即还给系统,避免不必要的内存占用。你的测试用例刚好触发了mmap机制
你一次性申请了10GB的内存,这个大小远大于默认的MMAP_THRESHOLD,所以malloc直接走了mmap路径。而2018年提问中的测试代码申请的是较小的内存块,触发的是brk分配方式,free后内存被glibc缓存,没有归还给系统,所以进程的内存占用看起来没有变化。代码里的小细节
你的代码中有个小疏漏:memset(p, 0, BUFSIZ);这里用了标准IO缓冲区大小的BUFSIZ(通常是8KB),而不是你定义的10GB的BUFSIZE。不过后面的循环遍历了整个内存区域并赋值,触发了Linux的按需分页机制,把所有虚拟内存映射到物理内存,所以这个疏漏不影响最终的测试结果。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

