3. 页表结构详解:多级页表、页表项(PTE)格式、标志位
页表是操作系统内存管理子系统的核心数据结构,负责将虚拟地址(VA)转换为物理地址(PA)。在 64 位体系结构下,虚拟地址空间巨大(例如 2^48 或 2^57 字节),若使用单级页表,将消耗无法接受的物理内存。因此,现代操作系统普遍采用多级页表结构,并结合硬件 MMU(内存管理单元)进行高效查找。
核心概念:多级页表的核心思想是将虚拟地址分割为多个索引字段,每一级索引对应一张页表。只有实际使用的虚拟地址范围才会分配对应的页表,从而大幅节省内存。
3.1 多级页表结构与地址翻译
以 x86-64 架构的 4 级页表为例(48 位虚拟地址,页大小 4KB),虚拟地址被划分为 5 个部分:
- Offset (12 bits):页内偏移,直接对应物理页内的字节位置。
- Page Number (36 bits):进一步分为 4 个 9-bit 的索引:PML4、PDPT、PD、PT。
翻译过程如下:
- MMU 从控制寄存器 CR3 中读取 PML4 页表的基地址。
- 使用虚拟地址的 PML4 索引(bits 47:39)在 PML4 表中查找,获得 PDPT 页表的基地址。
- 使用 PDPT 索引(bits 38:30)在 PDPT 表中查找,获得 PD 页表的基地址。
- 使用 PD 索引(bits 29:21)在 PD 表中查找,获得 PT 页表的基地址。
- 使用 PT 索引(bits 20:12)在 PT 表中查找,获得最终的物理页帧号(PFN)。
- 将 PFN 与 Offset 拼接,形成完整的物理地址。
性能关键点:每次地址翻译需要 4 次内存访问(查 4 级页表)。为了加速,CPU 引入了 TLB(Translation Lookaside Buffer,页表缓存),缓存最近使用的 VA→PA 映射,命中时无需遍历页表。
3.2 页表项(PTE)格式详解
页表项(PTE)是页表中的最小单元,每个 PTE 对应一个虚拟页到物理页的映射。在 x86-64 架构中,每个 PTE 大小为 8 字节(64 bits)。其核心字段如下:
| 位域 (Bits) | 字段名称 | 描述 |
|---|---|---|
| 63:52 | Reserved / NX (No-Execute) | 保留位或 NX 标志位(用于禁止执行代码)。 |
| 51:12 | Physical Page Number (PFN) | 物理页帧号,指向物理内存中的 4KB 页。 |
| 11:9 | Ignored / Available | 操作系统可用位,用于存储自定义元数据(如页的回收状态)。 |
| 8 | G (Global) | 全局页标志,防止 TLB 刷新时被清除。 |
| 7 | PAT (Page Attribute Table) | 页属性表索引,用于控制内存缓存类型。 |
| 6 | D (Dirty) | 脏页标志,表示该页已被写入。 |
| 5 | A (Accessed) | 访问标志,表示该页已被读取或写入。 |
| 4 | PCD (Page Cache Disable) | 页缓存禁用标志。 |
| 3 | PWT (Page Write Through) | 页写通标志。 |
| 2 | U/S (User/Supervisor) | 用户/超级用户权限位。 |
| 1 | R/W (Read/Write) | 读写权限位。 |
| 0 | P (Present) | 存在位,表示该页是否在物理内存中。 |
关键设计:PTE 的格式是硬件与软件协同的契约。操作系统必须遵循硬件定义的位布局,同时可以利用“Available”位(bits 11:9)存储内核私有数据,例如页的回收优先级或 Swap 状态。
3.3 关键标志位:Present, Dirty, Accessed
这三个标志位是页表回收与 Swap 协同设计的基石。硬件 MMU 在访问页时会自动更新这些位,操作系统则利用它们来决策页的回收、换出和写回。
3.3.1 Present (P) 位
- P = 1:页在物理内存中,MMU 正常翻译。
- P = 0:页不在物理内存中(可能已被换出到 Swap 或尚未分配)。此时 PTE 中的其他字段(如 PFN)被操作系统重新解释,通常用于存储 Swap 条目信息(如 Swap 分区编号和偏移量)。
回收触发:当访问 P=0 的页时,MMU 触发缺页异常(Page Fault)。操作系统在缺页处理程序中检查 PTE 内容,若包含 Swap 信息,则从磁盘换入该页;若为未分配页,则分配新物理页。
3.3.2 Accessed (A) 位
- 硬件行为:当 MMU 对页进行读取或写入访问时,自动将 A 位置 1。
- 软件用途:操作系统定期扫描页表,检查 A 位。若 A=1,表示该页近期被访问过,应避免回收;若 A=0,表示该页可能长时间未被使用,是回收的候选。
- 回收算法:操作系统在扫描后会清除 A 位,以便下次扫描时判断页的活跃度。这是实现近似 LRU(最近最少使用)算法的关键。
3.3.3 Dirty (D) 位
- 硬件行为:当 MMU 对页进行写入操作时,自动将 D 位置 1。
- 软件用途:D 位标识页是否被修改过(即是否为“脏页”)。回收脏页时,必须将其内容写回磁盘(Swap 或文件系统);回收干净页(D=0)时,可以直接丢弃,无需 I/O 操作。
- 性能影响:脏页的回收代价远高于干净页,因为涉及磁盘写入。操作系统在回收时会优先选择干净页。
调优启示:在内存压力场景下,操作系统应优先回收 A=0 且 D=0 的页(干净且未使用),避免不必要的磁盘 I/O。同时,定期扫描并清除 A 位是保持回收算法准确性的关键。