2. 虚拟内存与分页机制

2.1 虚拟地址空间与物理内存的抽象

现代操作系统通过虚拟内存为每个进程提供独立的、连续的地址空间,使进程无需关心物理内存的实际布局。CPU 发出的地址是虚拟地址(VA),经过内存管理单元(MMU)转换为物理地址(PA)。这种抽象隔离了进程,并允许程序使用比物理内存更大的地址空间。

核心概念:虚拟地址空间被划分为固定大小的页(Page),物理内存被划分为相同大小的页框(Page Frame)。页与页框之间的映射关系由页表(Page Table)维护。
虚拟地址到物理地址映射流程 虚拟地址 → 物理地址映射流程 虚拟地址空间 页 0, 页 1, … 页 N-1 MMU 查页表 页表 VPN → PFN 权限 / 标志位 物理地址 物理内存 页框 0, 页框 1, … 页框 M-1 说明 虚拟地址通过页表转换为物理地址。 页表项(PTE)记录虚拟页号(VPN)到物理页框号(PFN)的映射。

2.2 页框与页表项(PTE)

页框(Page Frame)是物理内存的最小分配单元,大小通常为 4KB(x86 架构)或 16KB(ARM 大页)。页表项(PTE)是页表中的条目,每个 PTE 对应一个虚拟页,包含以下关键字段:

字段 位宽(典型) 描述
物理页框号(PFN) 20–52 位 映射到的物理页框基地址
存在位(Present) 1 位 该页是否在物理内存中(否则触发缺页异常)
读写位(R/W) 1 位 允许读/写权限
用户/超级用户位(U/S) 1 位 区分用户态与内核态访问
脏位(Dirty) 1 位 页面是否被写入(用于换出策略)
访问位(Accessed) 1 位 页面是否被访问(用于页面置换算法)
性能提示:PTE 的访问位和脏位由硬件自动设置,操作系统定期扫描这些位以决定哪些页面可以换出。频繁的脏位检查会增加 TLB 缺失开销。

2.3 多级页表结构

对于 64 位地址空间,单级页表会占用巨大内存(例如 2^48 个 PTE × 8 字节 = 2 PB)。因此现代架构采用多级页表,将虚拟地址划分为多个索引层级,每级索引对应一个页表。只有实际使用的虚拟地址范围才会分配页表,大幅节省内存。

以 x86-64 的 4 级页表为例,虚拟地址被划分为:

  • PML4(Page Map Level 4):9 位索引,指向第 2 级页表
  • PDPT(Page Directory Pointer Table):9 位索引,指向第 3 级页表
  • PD(Page Directory):9 位索引,指向第 4 级页表
  • PT(Page Table):9 位索引,指向物理页框
  • Offset:12 位页内偏移(4KB 页)
4级页表遍历结构 x86-64 4级页表遍历结构 PML4 PDPT PD PT Offset (12位) PML4 表 512 条目 PDPT 表 512 条目 PD 表 512 条目 PT 表 512 条目 物理页框 4KB 数据 多级页表优势 只有实际使用的虚拟地址范围才分配页表,节省内存。 每级页表 512 条目(9 位索引),4 级共 36 位索引 + 12 位偏移 = 48 位虚拟地址。

2.4 多级页表遍历与 TLB 缺失

当 CPU 访问一个虚拟地址时,MMU 从最高级页表开始逐级查找:

  1. 从 CR3 寄存器(x86)或 TTBR(ARM)获取 PML4 基地址。
  2. 用虚拟地址的 PML4 索引找到对应条目,获取 PDPT 基地址。
  3. 用 PDPT 索引找到对应条目,获取 PD 基地址。
  4. 用 PD 索引找到对应条目,获取 PT 基地址。
  5. 用 PT 索引找到对应条目,获取物理页框号。
  6. 组合页框号 + 页内偏移得到物理地址。

每次页表遍历需要 4 次内存访问(4 级页表)。如果 TLB 未命中,这些访问会直接增加内存延迟。TLB 缺失率越高,页表遍历开销越显著。

性能陷阱:多级页表遍历的 4 次内存访问可能全部命中 L1/L2 缓存,也可能全部缺失导致主存访问。在数据库、HPC 等大内存工作负载中,TLB 缺失导致的页表遍历是主要瓶颈之一。

2.5 页表遍历路径优化方向

针对页表遍历路径的优化通常从以下角度切入:

优化方向 方法 预期效果
TLB 覆盖范围 使用大页(2MB/1GB)减少页表层级 减少 TLB 缺失次数
页表缓存 利用 MMU 的页表缓存(PWC) 加速页表遍历中间结果
预取 硬件 TLB 预取 / 软件预取 降低 TLB 缺失延迟
页表结构 使用虚拟化扩展(如 EPT/NPT) 减少虚拟机场景的页表遍历开销
工程实践:在 Linux 中,通过 hugepages 或透明大页(THP)可以显著降低 TLB 缺失率。对于内存密集型应用(如 Redis、数据库),建议显式配置大页。

2.6 本章小结

  • 虚拟内存通过页表实现虚拟地址到物理地址的映射。
  • 页表项(PTE)包含 PFN、权限位、状态位等关键信息。
  • 多级页表(如 x86-64 的 4 级页表)节省内存,但增加遍历开销。
  • TLB 缺失会触发完整的页表遍历,是性能优化的核心关注点。
  • 大页、页表缓存、预取等技术可有效优化页表遍历路径。