8张图讲清楚mmap实现原理
内容提要
本文介绍了Linux内核中mmap内存映射的实现原理,包括虚拟地址映射到物理地址的过程、mmap函数的实现原理以及Linux的缺页中断机制。
延伸解读
页表动态分配:避免内存浪费的关键
文章指出,64位CPU若为每个进程固定分配所有页表,仅页表本身就可能占用超过500GB内存。实际上,进程通常只使用少量虚拟内存,因此Linux采用动态分配策略:仅在访问虚拟地址时通过缺页中断创建所需页表。这种按需分配机制显著降低了内存开销,也是虚拟内存系统高效运行的基础。
VMA:虚拟内存映射的指导结构
VMA(虚拟内存区域)是mmap实现的核心,它描述了进程虚拟地址空间中一段连续区域的起始、结束地址及访问权限等属性。文章强调,没有VMA的指导,虚拟地址到物理地址的映射无法完成。mmap函数的主要工作就是创建VMA,后续缺页中断再根据VMA信息建立具体的页表映射。
文件映射与匿名映射的差异
文件映射将文件内容映射到进程内存,创建pte时需根据VMA记录的文件fd、偏移量和长度定位文件,将磁盘内容拷贝至物理页。匿名映射则简单得多,只需申请一个物理内存页并转换为pte即可。两者在VMA的vm_file、vm_pgoff等成员上有明显区别,文件映射需指定这些参数,匿名映射则无需。
缺页中断:映射建立的触发点
通过mmap创建VMA后,虚拟地址并未立即映射到物理地址,因为页表尚未动态创建。当进程访问这些虚拟地址时,会触发缺页中断,中断处理函数负责创建各级页表(pgd、pud、pmd、ptl)以及最终的pte。这一过程需要结合task_struct->mm_struct->pgd和虚拟地址偏移量完成,是虚拟地址到物理地址映射得以实现的关键步骤。
Q&A
mmap在Linux内核中有什么作用?
mmap用于将文件或设备映射到进程的地址空间,使得进程可以像访问内存一样访问这些文件或设备。
虚拟地址是如何映射到物理地址的?
虚拟地址通过页表机制映射到物理地址,64位CPU使用4级页表,依次查询pgd、pud、pmd和ptl表。
缺页中断的作用是什么?
缺页中断在访问未建立映射关系的虚拟内存时触发,负责创建映射表以完成虚拟地址到物理地址的映射。
mmap函数的实现分为哪几种类型?
mmap函数主要分为文件映射和匿名映射两种类型。
VMA在mmap中有什么作用?
VMA(虚拟内存区域)用于管理进程的虚拟内存,指导虚拟地址和物理地址的映射。
为什么64位CPU的虚拟地址只使用48位?
64位CPU的虚拟地址长度为64位,但实际使用48位即可满足映射需求,因其地址空间可达256TB。