首页/操作系统/03-memory/页表结构详解 🔗 在 Obsidian 中打开
操作系统 · 03-memory

页表结构详解

重要度 ⭐⭐⭐⭐⭐ 难度 ⭐⭐⭐考查频率 低 操作系统/内存管理多级页表倒排页表页表项地址转换
速查
32 位 + 4KB 页的单级页表需 $2^{20}$ 项 × 4B = 4MB多级页表按需分配、每级恰好一页;倒排页表以物理页框号为索引,大小与物理内存成正比。

速查

项目
核心概念页表结构详解
关键公式 / 性质每个 PTE 4 字节 → 页表大小 = 4MB
考试频率⭐⭐⭐⭐⭐

一、基本概念

页表是虚拟地址到物理地址的映射表,每个进程拥有独立的页表

页表项(PTE)结构

┌────────────────────────────────────────────────┐
│         物理页框号 (PFN)          │ 控制位     │
├───────────────────────────────────┼───────────┤
│  31                    12 │ 11  0│
│  物理页框号(20bit)        │ 标志位 │
└───────────────────────────────────┴───────────┘
32 位页表项(PTE)位域 物理页框号 PFN bit 31 … 12(20 bit) 控制标志位 bit 11 … 0(12 bit) P R/W U/S A D 高 20 位左移 12 位即得页框基址
图:PTE = 物理页框号(高 20 位) + 控制标志位(低 12 位)。

关键标志位

名称说明
0Present (P)页是否在内存中
1Read/Write (R/W)读写权限
2User/Supervisor (U/S)用户 / 内核访问权限
3Page-level Cache Disable (PCD)禁用缓存
4Accessed (A)是否被访问过(用于置换算法)
5Dirty (D)是否被修改过(写回策略)
6Page Size (PS)页大小(用于大页)
7Global (G)全局页(TLB 不失效)

二、单级页表(线性页表)

结构

虚拟地址: [页号(20bit)] [页内偏移(12bit)]
           ↓
       查页表
           ↓
       物理页框号 + 页内偏移 → 物理地址

问题

  • 32 位地址空间、4KB 页大小:需要 $2^{20}$ 个页表项
  • 每个 PTE 4 字节 → 页表大小 = 4MB
  • 每个进程都需要一个页表 → 浪费大量内存
规模爆炸$2^{20} \times 4\text{B} = 4\text{MB}$,且必须连续存放。若有 100 个进程,仅页表就要 400MB——这正是引入多级页表的直接动机。

三、多级页表

二级页表(x86 32 位)

虚拟地址 (32bit):
┌──────────┬──────────┬──────────┐
│ 一级索引 │ 二级索引 │ 页内偏移 │
│ (10bit)  │ (10bit)  │ (12bit)  │
└────┬─────┴────┬─────┴──────────┘
     │          │
     ▼          │
 一级页表(页目录) │
 ┌─────────┐    │
 │ PDE[0]  │────┼──→ 二级页表0
 │ PDE[1]  │    │    ┌─────────┐
 │ ...     │    └───→│ PTE[0]  │──→ 物理页框
 │ PDE[1023]│        │ PTE[1]  │──→ 物理页框
 └─────────┘        │ ...     │
                     └─────────┘

优势

  • 一级页表(页目录)常驻内存:4KB(1024 项 $\times 4$ 字节)
  • 二级页表按需创建:只映射实际使用的地址空间
  • 节省内存:未使用的虚拟地址区域不需要创建页表

x86-64 四级页表

虚拟地址 (48bit有效):
┌──────┬──────┬──────┬──────┬──────────┐
│ PML4 │ PDPT │  PD  │  PT  │  Offset  │
│(9bit)│(9bit)│(9bit)│(9bit)│ (12bit)  │
└──────┴──────┴──────┴──────┴──────────┘
  Level4  Level3  Level2  Level1

四级页表结构:

CR3寄存器 → PML4表 → 页目录指针表(PDPT)
                         → 页目录(PD)
                              → 页表(PT)
                                   → 物理页框

各级页表大小

级别条目数每项大小表大小
PML45128 字节4KB
PDPT5128 字节4KB
PD5128 字节4KB
PT5128 字节4KB
设计巧思每级页表恰好一个物理页(4KB):$2^{9} \times 8\text{B} = 4\text{KB}$。这正是索引位宽取 9 bit 的原因——让页表自身也能被分页管理。

四、大页(Huge Page)

2MB 大页(跳过最后一级页表)

PD项的PS位=1 → 该PD项直接映射2MB物理区域
减少一级页表查找,提高TLB覆盖率

1GB 大页(跳过最后两级页表)

PDPT项的PS位=1 → 直接映射1GB物理区域
用于数据库、虚拟机等大内存应用

大页的优势

  • 减少 TLB miss(覆盖更大地址范围)
  • 减少页表内存开销
  • 减少页表遍历次数
为什么是 2MB / 1GB省掉最低一级 9 bit 索引后,页内偏移从 12 bit 变为 $12+9=21$ bit,即 $2^{21}=2\text{MB}$;再省一级则为 $2^{30}=1\text{GB}$。

五、倒排页表(Inverted Page Table)

问题

传统页表以虚拟页号为索引,64 位地址空间页表过大。

结构

物理页框号为索引,表项记录哪个进程的哪个虚拟页映射到此。

物理页框号    进程PID    虚拟页号
──────────────────────────────
0            P1        5
1            P2        10
2            P1        3
3            (空闲)
...

地址转换

输入: (PID, 虚拟页号)
  → 搜索倒排页表(用哈希加速)
  → 找到对应的物理页框号
  → 物理地址 = 物理页框号 + 页内偏移

优缺点

优点缺点
内存占用与物理内存成正比地址转换需要搜索(哈希查找)
适合 64 位大地址空间共享内存实现困难
需要哈希表辅助

六、页表寄存器

CR3 寄存器(x86)

  • 存储当前进程页目录的物理地址
  • 进程切换时,CR3 随之切换

页表基址寄存器(PTBR)

  • 存储页表起始地址
  • 进程切换时更新
易错CR3 中存放的是物理地址(否则会陷入"翻译地址需要先翻译地址"的死循环);切换 CR3 会导致非 Global 的 TLB 表项整体失效。

七、地址转换过程(完整流程)

CPU发出虚拟地址VA
       │
       ▼
┌──────────────┐
│ 查TLB         │
│ (用VPN查)     │
└──────┬───────┘
       │
  ┌────┴────┐
  │ 命中?    │
  └────┬────┘
   Yes │    No
   ┌───┘    └───┐
   ▼            ▼
 直接获得PFN   遍历页表
   │           │
   │     ┌─────┴─────┐
   │     │ 页表项有效? │
   │     └─────┬─────┘
   │      Yes  │  No
   │     ┌─────┘    └──→ 缺页中断
   │     ▼
   │   更新TLB
   │     │
   └─────┤
         ▼
  物理地址 = PFN + Offset
访存次数无 TLB 的 $k$ 级页表:访问一次数据需 $k+1$ 次访存;TLB 命中时仅 1 次。这是计算 $EAT$ 的基础。

记忆卡片

为什么需要多级页表?单级页表有什么问题?
单级页表大小与虚拟地址空间成正比(32 位需 4MB),多级页表按需分配,只映射实际使用的区域。
x86-64 的四级页表分别是哪四级?
PML4(9bit) → PDPT(9bit) → PD(9bit) → PT(9bit) → Offset(12bit),每级页表恰好 4KB。
倒排页表的索引是什么?为什么需要它?
以物理页框号为索引。64 位地址空间若用传统页表太大,倒排页表大小与物理内存成正比。
大页(Huge Page)的优势是什么?
减少 TLB miss(覆盖更大范围)、减少页表内存开销、减少页表遍历次数。

交互动画 · x86-64 四级页表遍历

48 位虚拟地址字段划分 PML447–39 (9b) PDPT38–30 (9b) PD29–21 (9b) PT20–12 (9b) Offset11–0 (12b) CR3基址 PML4 表512 项 · 4KB PDPT512 项 · 4KB PD512 项 · 4KB PT→ PFN 物理地址PFN << 12 | Offset
点击「下一步」,逐级走完一次 page walk
访存次数:0
示意图:CR3 提供 PML4 基址,虚拟地址的 4 个 9 位字段依次充当各级页表索引,最低 12 位偏移直接拼接到 PFN 之后。

相关知识点

paging-and-segmentation tlb-translation-lookaside virtual-memory-management

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。