1. 虚拟内存基础
1.1 为什么需要虚拟内存?
在早期的计算机系统中,程序直接访问物理内存。这种方式存在三个致命缺陷:地址空间不隔离(一个程序可以改写另一个程序的内存)、内存使用效率低(碎片化严重)、程序地址不确定(每次加载的物理基址不同)。虚拟内存正是为了解决这些问题而诞生的核心抽象。
核心思想:每个进程拥有独立的虚拟地址空间(如 32 位系统为 4GB),通过硬件和操作系统协作,将虚拟地址动态转换为物理地址。进程以为自己独占整个内存,实际上物理内存由操作系统统一管理。
1.2 虚拟地址与物理地址的映射原理
虚拟地址(VA)是 CPU 发出的地址,物理地址(PA)是内存总线上的真实地址。映射的基本单位是页(Page),而非单个字节。典型的页大小为 4KB。
映射过程的核心公式:
虚拟地址 = 虚拟页号 (VPN) + 页内偏移 (Offset)
物理地址 = 物理页框号 (PFN) + 页内偏移 (Offset)
页内偏移在映射前后保持不变,转换的本质是 VPN → PFN 的查找过程。
1.3 MMU(内存管理单元)的作用
MMU 是 CPU 内部的一个硬件模块,负责自动完成虚拟地址到物理地址的转换。它位于 CPU 核心和内存总线之间,是虚拟内存机制的硬件执行者。
| 功能模块 | 职责描述 | 性能影响 |
|---|---|---|
| 地址转换 | 接收 CPU 发出的虚拟地址,输出物理地址 | 每次内存访问都需转换 |
| TLB 管理 | 缓存最近使用的页表项,加速转换 | TLB hit 延迟约 1 个时钟周期 |
| 权限检查 | 验证访问类型(读/写/执行)是否允许 | 防止越权访问 |
| 缺页处理触发 | 页表项无效时,向操作系统发出缺页异常 | 触发软件处理流程 |
性能关键点:MMU 的转换速度直接影响程序执行效率。TLB(Translation Lookaside Buffer)是 MMU 内部的硬件缓存,用于避免每次转换都访问内存中的页表。TLB miss 是后续章节的核心优化对象。
1.4 页表的基本概念
页表是操作系统为每个进程维护的数据结构,存储在物理内存中。它的每一项(Page Table Entry, PTE)记录了虚拟页号到物理页框号的映射关系,以及该页的访问权限和状态信息。
页表项(PTE)的典型结构
| 位 63-12: 物理页框号 (PFN) | 位 11-9: 保留/软件可用 | 位 8: 全局 (G) |
| 位 7: 页大小 (PS) | 位 6: 脏位 (D) | 位 5: 访问位 (A) |
| 位 4-3: 缓存策略 (PCD/PWT) | 位 2: 用户/超级用户 (U/S) |
| 位 1: 读写 (R/W) | 位 0: 存在位 (Present) |
| 标志位 | 名称 | 含义 |
|---|---|---|
| 位 0 (P) | 存在位 | 1=页在物理内存中;0=页不在内存(触发缺页异常) |
| 位 1 (R/W) | 读写位 | 1=可读写;0=只读 |
| 位 2 (U/S) | 用户/超级用户 | 1=用户态可访问;0=仅内核态可访问 |
| 位 5 (A) | 访问位 | 硬件自动置 1,表示该页被访问过 |
| 位 6 (D) | 脏位 | 硬件自动置 1,表示该页被写过(换出时需写回磁盘) |
多级页表结构
现代 64 位系统使用多级页表(如 x86-64 的 4 级页表),避免为整个 64 位地址空间预分配巨大的单级页表。多级页表按需分配中间页表,节省内存。
1.5 缺页异常(Page Fault)的触发条件
当 MMU 在页表中查找 VPN 对应的 PTE 时,如果存在位(Present bit)为 0,MMU 无法完成转换,会触发一个缺页异常,将控制权交给操作系统内核的缺页异常处理程序。
注意区分:缺页异常 ≠ 程序错误。它是虚拟内存的正常工作机制,用于实现按需加载、写时复制、页面换入换出等核心功能。频繁的缺页异常会导致性能急剧下降(系统抖动)。
缺页异常的三种类型
- 硬缺页(Major Page Fault):所需页面不在物理内存中,需要从磁盘换入。这是最耗时的缺页类型,可能涉及磁盘 I/O。
- 软缺页(Minor Page Fault):页面已在物理内存中,但页表项未建立映射(如共享页面首次访问)。只需建立页表项,无需磁盘 I/O。
- 无效访问(Segmentation Fault):访问的虚拟地址未映射任何物理页面(如空指针解引用),操作系统直接终止进程。
1.6 本章小结
| 概念 | 核心要点 |
|---|---|
| 虚拟地址 | 进程看到的连续地址空间,由 VPN + 偏移组成 |
| 物理地址 | 内存总线上的真实地址,由 PFN + 偏移组成 |
| MMU | 硬件地址转换单元,负责查页表、权限检查、触发缺页异常 |
| 页表 | 存储 VPN→PFN 映射的数据结构,每个进程独立拥有 |
| 缺页异常 | 页表项无效时触发的异常,由操作系统内核处理 |