8张图讲清楚mmap实现原理
内容提要
本文介绍了Linux内核中mmap内存映射的实现原理,通过页表机制将虚拟地址映射到物理地址,包括文件映射和匿名映射。
延伸解读
页表动态分配:避免内存浪费的关键
文章指出,64位CPU若为每个进程固定分配所有页表,仅页表就需占用超过500GB内存。实际上,进程通常只使用少量虚拟内存,因此Linux内核采用动态分配策略,仅在访问虚拟地址时通过缺页中断逐步创建所需页表。这种按需分配机制显著降低了内存开销,是多进程环境下内存管理高效运行的基础。
VMA:虚拟内存映射的指导结构
VMA(虚拟内存区域)是Linux内核管理进程虚拟地址空间的核心数据结构,记录了区域的起始、结束地址及访问权限等属性。文章强调,没有VMA的指导,虚拟地址到物理地址的映射无法完成。VMA不仅描述代码段、数据段、堆、栈等区域,还决定了映射是文件映射还是匿名映射,是理解mmap实现原理的关键环节。
缺页中断:连接虚拟与物理的桥梁
通过mmap创建VMA后,虚拟地址并未立即映射到物理地址,因为对应的页表尚未建立。当进程访问这些地址时,会触发缺页中断。中断处理函数根据VMA和虚拟地址偏移,动态创建各级页表,并最终建立PTE映射。这一过程将虚拟地址与物理页面关联起来,是mmap映射生效的必要步骤。
文件映射与匿名映射的差异
文件映射将文件内容映射到进程内存,创建PTE时需根据VMA中的文件信息、偏移量和长度,将磁盘文件内容拷贝至物理内存页,再转换为PTE。匿名映射则简单得多,直接申请一个物理内存页并转换为PTE即可。两者在PTE创建时的数据来源不同,文件映射涉及磁盘I/O,而匿名映射仅分配内存,这影响了它们的性能和使用场景。
Q&A
mmap在Linux内核中的作用是什么?
mmap在Linux内核中用于将文件或设备映射到进程的地址空间,使得进程可以像访问内存一样访问这些文件或设备。
虚拟地址是如何映射到物理地址的?
虚拟地址通过页表机制映射到物理地址,64位CPU采用4级页表,依次查询pgd、pud、pmd和ptl表来完成映射。
缺页中断的作用是什么?
缺页中断在访问未建立映射关系的虚拟内存时触发,负责分配物理页面并建立虚拟地址与物理地址的映射关系。
文件映射和匿名映射有什么区别?
文件映射将文件内容映射到进程内存,需要指定文件fd和偏移量,而匿名映射则是直接申请物理内存页,不涉及文件。
VMA在mmap中有什么作用?
VMA(虚拟内存区域)用于管理进程的虚拟内存,包含起始地址、结束地址及属性信息,是虚拟地址与物理地址映射的指导结构。
64位CPU的页表机制是怎样的?
64位CPU采用4级页表,虚拟地址长度为64位,实际使用48位,pgd、pud、pmd、ptl表偏移均为9位,物理页偏移为12位。