面试不懂 Linux 内存管理?我用 20 张图给你讲明白

对于精通 CURD 的业务同学,内存管理好像离我们很远,但这个知识点虽然冷门(估计很多人学完根本就没机会用上)但绝对是基础中的基础 。
这就像武侠小说中的内功修炼,学完之后看不到立竿见影的效果,但对你日后的开发工作是大有裨益的,因为你站的更高了 。
文中所有示例图都是我亲手画的,画图比码字还费时间,但大家看图理解比文字更直观,所以还是画了 。需要高清示例图片的同学,文末有获取方式自取 。
再功利点的说,面试的时候不经意间透露你懂这方面知识,并且能说出个一二三来,也许能让面试官对你更有兴趣,离升职加薪,走上人生巅峰又近了一步 。
前提约定:本文讨论技术内容前提,操作系统环境都是 x86架构的 32 位 linux系统 。
虚拟地址即使是现代操作系统中,内存依然是计算机中很宝贵的资源,看看你电脑几个T固态硬盘,再看看内存大小就知道了 。
为了充分利用和管理系统内存资源,Linux采用虚拟内存管理技术,利用虚拟内存技术让每个进程都有4GB 互不干涉的虚拟地址空间 。
进程初始化分配和操作的都是基于这个「虚拟地址」,只有当进程需要实际访问内存资源的时候才会建立虚拟地址和物理地址的映射,调入物理内存页 。
打个不是很恰当的比方,这个原理其实和现在的某某网盘一样 。假如你的网盘空间是1TB,真以为就一口气给了你这么大空间吗?那还是太年轻,都是在你往里面放东西的时候才给你分配空间,你放多少就分多少实际空间给你,但你和你朋友看起来就像大家都拥有1TB空间一样 。
 
虚拟地址的好处

  • 避免用户直接访问物理内存地址,防止一些破坏性操作,保护操作系统
  • 每个进程都被分配了4GB的虚拟内存,用户程序可使用比实际物理内存更大的地址空间
4GB 的进程虚拟地址空间被分成两部分:「用户空间」和「内核空间」
面试不懂 Linux 内存管理?我用 20 张图给你讲明白

文章插图
 
用户空间内核空间
物理地址上面章节我们已经知道不管是用户空间还是内核空间,使用的地址都是虚拟地址,当需进程要实际访问内存的时候,会由内核的「请求分页机制」产生「缺页异常」调入物理内存页 。
把虚拟地址转换成内存的物理地址,这中间涉及利用MMU 内存管理单元(Memory Management Unit ) 对虚拟地址分段和分页(段页式)地址转换,关于分段和分页的具体流程,这里不再赘述,可以参考任何一本计算机组成原理教材描述 。
面试不懂 Linux 内存管理?我用 20 张图给你讲明白

文章插图
 
段页式内存管理地址转换
Linux 内核会将物理内存分为3个管理区,分别是:
ZONE_DMADMA内存区域 。包含0MB~16MB之间的内存页框,可以由老式基于ISA的设备通过DMA使用,直接映射到内核的地址空间 。
ZONE_NORMAL普通内存区域 。包含16MB~896MB之间的内存页框,常规页框,直接映射到内核的地址空间 。
ZONE_HIGHMEM高端内存区域 。包含896MB以上的内存页框,不进行直接映射,可以通过永久映射和临时映射进行这部分内存页框的访问 。
面试不懂 Linux 内存管理?我用 20 张图给你讲明白

文章插图
 
物理内存区划分
用户空间用户进程能访问的是「用户空间」,每个进程都有自己独立的用户空间,虚拟地址范围从从 0x00000000 至 0xBFFFFFFF 总容量3G。
用户进程通常只能访问用户空间的虚拟地址,只有在执行内陷操作或系统调用时才能访问内核空间 。
进程与内存进程(执行的程序)占用的用户空间按照「 访问属性一致的地址空间存放在一起 」的原则,划分成 5个不同的内存区域 。访问属性指的是“可读、可写、可执行等。