一文读懂Linux内存分配策略

💡 原文中文,约4900字,阅读约需12分钟。
📝

内容提要

本文以问答形式深入探讨了Linux内存系统的分配策略,包括虚拟地址空间的划分和用户空间内存的动态分配方式。malloc函数通过brk和mmap系统调用分配内存,其中brk方式不会归还内存给操作系统,而mmap方式会归还。预分配内存池可以减少系统调用和缺页中断的次数。

🔎

延伸解读

brk与mmap的权衡:为何不只用一种?

文章指出,brk分配的内存free后不归还操作系统,而是缓存在内存池中,这减少了系统调用和缺页中断,但可能产生内存碎片,且这种“泄露”难以用valgrind检测。mmap分配的内存free后会归还,但每次分配都涉及系统调用和缺页中断,CPU开销大。因此,malloc默认以128KB为阈值,大块内存用mmap,小块用brk,以平衡性能与内存利用率。

malloc(1)为何实际分配132KB?

文章通过实验展示,malloc(1)实际通过brk预分配了132KB的堆空间。这是因为malloc使用内存池策略,预分配更大空间以减少频繁系统调用。返回的地址比堆起始地址多16字节,用于存储内存块描述信息,free时通过偏移获取大小。这解释了malloc并非按需精确分配,而是有内部管理机制。

free释放内存:归还与否取决于分配方式

free释放内存时,是否归还操作系统取决于malloc的分配方式。通过brk分配的内存,free后仍保留在堆中,缓存在内存池供复用;通过mmap分配的内存,free后会真正归还。文章通过实验验证:申请128KB内存触发mmap,free后地址从maps中消失。这提醒开发者,内存释放并不总是立即减少进程占用。

❓

Q&A

Linux内存系统是如何划分的?

Linux内存系统分为内核空间和用户空间,32位系统内核占1G,64位系统内核和用户空间各占128T。

malloc函数是如何分配内存的?

malloc函数通过brk和mmap系统调用分配内存,brk用于小于128KB的内存分配,mmap用于大于128KB的内存分配。

使用brk和mmap的内存分配有什么区别?

brk分配的内存不会归还给操作系统,而mmap分配的内存会在释放时归还。

malloc分配的虚拟内存会占用物理内存吗?

不会,malloc分配的虚拟内存未被访问时不会映射到物理内存。

为什么malloc会预分配内存池?

预分配内存池可以减少系统调用和缺页中断的次数,从而提高性能。

free函数释放内存时会归还给操作系统吗?

通过brk分配的内存不会归还,而通过mmap分配的内存会归还给操作系统。

🏷️

标签

➡️

继续阅读