1. 内存管理基础:物理内存与虚拟内存概念、MMU与页表的作用、页表层级结构
1.1 物理内存与虚拟内存
现代操作系统采用虚拟内存机制,为每个进程提供独立的、连续的地址空间,而底层实际存储则映射到物理内存(RAM)或磁盘交换区。这种抽象层解决了物理内存碎片化、进程隔离、以及地址空间不足等核心问题。
| 概念 | 定义 | 关键特征 |
|---|---|---|
| 物理内存 | 硬件 RAM 芯片提供的实际存储单元,以字节编址 | 容量有限、多进程共享、地址不连续 |
| 虚拟内存 | 操作系统为每个进程创建的抽象地址空间 | 独立、连续、可大于物理内存、通过页表映射 |
| 地址映射 | 虚拟地址 → 物理地址的转换过程 | 由 MMU 硬件完成,操作系统维护页表 |
1.2 MMU 与页表的作用
内存管理单元(MMU)是 CPU 内部的硬件模块,负责将 CPU 发出的虚拟地址实时转换为物理地址。页表(Page Table)是存储在内存中的数据结构,记录了虚拟页号(VPN)到物理页框号(PFN)的映射关系。
MMU 的工作流程如下:
- CPU 执行指令,发出虚拟地址。
- MMU 截获该地址,提取虚拟页号(VPN)和页内偏移(Offset)。
- MMU 查询当前进程的页表,查找 VPN 对应的页表项(PTE)。
- 若 PTE 有效且权限允许,取出物理页框号(PFN)。
- 组合 PFN + Offset 生成最终物理地址,访问内存。
- 若 PTE 无效(缺页),触发缺页异常,由操作系统处理。
1.3 页表层级结构
现代 64 位系统(如 x86_64、ARMv8)不再使用单级页表,而是采用多级页表(通常为 4 级或 5 级)。多级页表的核心优势在于:按需分配——只有实际使用的虚拟地址范围才需要分配页表层级,大幅节省内存。
以 x86_64 的 4 级页表为例,虚拟地址被划分为以下字段:
| 字段 | 位宽 | 作用 |
|---|---|---|
| PML4 | 9 bits | 顶级页表索引(Page Map Level 4) |
| PDPT | 9 bits | 页目录指针表索引(Page Directory Pointer Table) |
| PD | 9 bits | 页目录索引(Page Directory) |
| PT | 9 bits | 页表索引(Page Table) |
| Offset | 12 bits | 页内偏移(4KB 页面) |
地址转换时,MMU 依次遍历 PML4 → PDPT → PD → PT 四级表,每级表从内存中读取一个 512 项的页表数组(每项 8 字节),最终找到物理页框号。这个过程称为页表遍历(Page Table Walk)。
1.4 标准页面大小与 TLB 覆盖范围
标准页面大小为 4KB(x86/ARM 架构)。TLB 作为页表的硬件缓存,其条目数量有限(通常 32~1024 项)。TLB 覆盖范围 = TLB 条目数 × 页面大小。
例如,一个具有 64 个 TLB 条目的 CPU,使用 4KB 页面时,TLB 只能覆盖 64 × 4KB = 256KB 的连续内存区域。对于数据库、HPC 等需要大内存工作集的场景,这会导致频繁的 TLB 未命中,严重拖累性能。
| 页面大小 | TLB 条目数(示例) | TLB 覆盖范围 | 典型应用场景 |
|---|---|---|---|
| 4KB | 64 | 256 KB | 通用桌面、小内存进程 |
| 2MB | 64 | 128 MB | 数据库、虚拟化、中间件 |
| 1GB | 64 | 64 GB | HPC、大型内存数据库 |
1.5 页表层级与 TLB 命中的关系
页表层级深度直接影响 TLB 未命中时的惩罚成本:
- 4KB 标准页:4 级页表遍历,TLB 未命中代价约 100~200 纳秒(4 次内存访问)。
- 2MB 大页:跳过 PT 级,仅需 3 级遍历(PML4 → PDPT → PD),TLB 未命中代价降低约 25%。
- 1GB 大页:跳过 PT 和 PD 级,仅需 2 级遍历(PML4 → PDPT),TLB 未命中代价降低约 50%。
更重要的是,大页减少了页表本身的内存占用。一个 4KB 页面的完整 4 级页表项需要 4 个条目(每级一个),而 2MB 大页只需要 3 个条目,1GB 大页只需要 2 个条目。这意味着页表占用的内存更少,CPU 缓存(L2/L3)可以缓存更多的页表数据,间接提升 TLB 命中率。