1. 页表基础概念:虚拟地址与物理地址映射、页表的作用、多级页表结构

1.1 虚拟地址与物理地址映射

现代操作系统采用虚拟内存管理,每个进程拥有独立的虚拟地址空间(如 64 位 Linux 下 128 TB 用户空间)。CPU 发出的地址是虚拟地址(VA),必须转换为物理地址(PA)才能访问实际内存。页表(Page Table)正是完成这一转换的核心数据结构。

核心公式: 虚拟地址 → 页表(多级查询) → 物理地址 + 页内偏移

虚拟地址被划分为两部分:虚拟页号(VPN) 和 页内偏移(Offset)。页表将 VPN 映射到物理页框号(PFN),PFN 与 Offset 拼接即得到物理地址。

地址成分 说明 示例(4KB 页)
虚拟页号(VPN) 页表索引,决定映射到哪个物理页框 高 52 位(64 位地址中)
页内偏移(Offset) 页内字节位置,直接作为物理地址低 12 位 低 12 位(0x000–0xFFF)
物理页框号(PFN) 页表项中记录的物理页框编号 如 0x7f000
物理地址(PA) PFN 左移 12 位 + Offset 0x7f000000 + 0x123 = 0x7f000123
虚拟地址 → 物理地址转换流程 虚拟地址(VA) VPN Offset 页表(多级查询) VPN → PFN 映射 PFN 物理地址(PA) PFN << 12 + Offset

1.2 页表的作用

页表是虚拟内存系统的基石,承担以下关键职责:

  • 地址转换: 将虚拟地址映射到物理地址,使进程看到连续的虚拟空间,而物理内存可以碎片化。
  • 内存保护: 页表项(PTE)包含权限位(读/写/执行)、用户/内核态标志,防止进程越权访问。
  • 按需分页: 页表项中的 Present 位标记页面是否在物理内存中。缺页时触发 Page Fault,由内核加载数据。
  • 共享内存: 多个进程的虚拟页可映射到同一物理页框,实现高效进程间通信(IPC)。
  • 交换支持: 页表项可记录页面在磁盘交换区的位置,实现虚拟内存大于物理内存。
性能关键: 每次内存访问都需要查页表。若页表全部在内存中,一次访存将变为多次内存访问(多级页表查询 + 实际访存)。TLB(Translation Lookaside Buffer)作为页表的高速缓存,是缓解此瓶颈的核心硬件。

1.3 多级页表结构

64 位系统虚拟地址空间巨大(如 248 或 257 字节),若使用单级页表,页表本身将占用海量内存。多级页表通过分层索引,只分配实际使用的页表层级,大幅节省内存。

以 x86-64 Linux 的 4 级页表为例(PGD → P4D → PUD → PMD → PTE),虚拟地址被划分为 5 个部分:

层级 全称 位宽(典型) 作用
PGD Page Global Directory 9 位 顶级目录,每个进程一个
P4D Page 4th Level Directory 9 位 第 4 级目录(某些架构可选)
PUD Page Upper Directory 9 位 第 3 级目录
PMD Page Middle Directory 9 位 第 2 级目录
PTE Page Table Entry 9 位 最后一级,指向物理页框
Offset 页内偏移 12 位 4KB 页内寻址

地址转换时,CPU 从虚拟地址中依次提取各级索引,逐级查找页表目录,最终找到物理页框号。若某级目录项为空(未分配),则停止查找,触发缺页异常。

x86-64 4 级页表地址转换结构 虚拟地址(64 位,实际使用 48 位) PGD (9b) P4D (9b) PUD (9b) PMD (9b) PTE (9b) Offset (12b) PGD 表 512 项 P4D 表 512 项 PUD 表 512 项 PMD 表 512 项 PTE 表 512 项 物理页框 4KB / 2MB / 1GB 每级页表占用 512 × 8 字节 = 4KB(一个物理页),未使用的页表层级不分配物理内存 大页(Huge Pages)可跳过 PMD 或 PUD 级,减少页表层级和 TLB 压力

1.4 页表项(PTE)结构

每个页表项通常为 8 字节(64 位),包含物理页框号及标志位。以 x86-64 为例:

位域 宽度 说明
PFN 高 52 位(实际使用 40 位) 物理页框号,指向 4KB 对齐的物理页
Present (P) 1 位 页面是否在物理内存中(0 则触发缺页)
Read/Write (R/W) 1 位 0 表示只读,1 表示可读写
User/Supervisor (U/S) 1 位 0 仅内核可访问,1 用户态也可访问
Page-level Write-Through (PWT) 1 位 缓存写策略:透写/回写
Page-level Cache Disable (PCD) 1 位 禁止缓存该页
Accessed (A) 1 位 硬件置位,表示页面被访问过(用于页面置换)
Dirty (D) 1 位 硬件置位,表示页面被写入过(用于回写交换)
Global (G) 1 位 全局页,TLB 刷新时不清除(常用于内核空间)
注意: 多级页表每级目录项的结构与 PTE 类似,但 PFN 指向的是下一级页表的物理地址,而非数据页框。最后一级(PTE)的 PFN 才指向实际数据页。

1.5 多级页表的优势与权衡

  • 节省内存: 只分配实际使用的页表层级。例如,一个只使用少量内存的进程,其 PGD 和少量 PUD/PMD/PTE 即可,无需为整个地址空间分配页表。
  • 按需分配: 各级页表在首次访问对应虚拟地址范围时才创建,延迟分配。
  • 支持大页: 通过跳过中间层级(如 PMD 或 PUD),可直接映射 2MB 或 1GB 的大页,减少页表项数量。
  • 代价: 地址转换需要多次内存访问(4 级页表需 4 次查表 + 1 次数据访问),TLB 缺失时开销显著。