操作系统 - 按需分页
我们在上一章已经讨论了分页的概念。在本章中,我们将讨论什么是按需分页以及它是如何工作的。本章将涵盖以下主题 -
- 什么是按需分页?
- 按需分页如何工作?
- 按需分页示例
- 按需分页 vs 预分页
什么是按需分页?
按需分页是在分页内存管理方法之上的优化。在按需分页中,进程的页面仅在需要时(即按需)才加载到内存中,而不是在进程启动时一次性加载所有页面。
要理解按需分页,假设一个进程试图访问当前不在物理内存(RAM)中的页面。这将导致缺页中断。因此,操作系统从虚拟内存(磁盘)加载所需的页面到物理内存。这是根据进程的需求发生的,因此称为按需分页。如果在加载新页面时物理内存的帧已满,则操作系统使用页面置换算法来决定需要移除哪些页面以为新页面腾出空间。
下图展示了一个按需分页的实例。它突出了系统中在按需分页事件中发生的一系列活动 -
在图中,
- CPU 请求 Page 2 − 首先,CPU 请求 Page 2。使用页表检查 Page 2 是否在主内存中。在这种情况下,它不在。因此发生缺页中断。
- 缺页中断处理 − 操作系统收到缺页中断通知。它在磁盘上定位 Page 2 并在主内存中找到一个空闲帧。
- 加载页面 − 操作系统从磁盘将 Page 2 加载到主内存中的空闲帧。然后更新页表中 Page 2 的新帧号。
- 恢复进程 − 最后,通知 CPU Page 2 现在已在内存中,进程可以继续执行。
按需分页的工作原理
以下是按需分页工作过程的详细逐步解释 −
1. 页表和有效/无效位
CPU 中的每个进程都有一个 page table,它将虚拟地址映射到物理地址。对于页表中的每个条目,有一列称为 valid/invalid bit。如果这个位设置为 valid,则表示对应的页当前位于物理内存 (RAM) 中。如果设置为 invalid,则表示该页不在物理内存中,而是存储在磁盘上。访问无效页将导致 page fault。
2. Page Fault 处理
当进程尝试访问物理内存中的一个页时,CPU 会检查页表。在页表中,如果 valid/invalid bit 设置为 invalid,则发生 page fault。此时操作系统将执行以下步骤:
- 在磁盘上定位页 OS 查找所需页存储在磁盘上的位置。
- 找到空闲帧 − OS 检查物理内存 (RAM) 中是否有空闲帧。如果没有空闲帧可用,则使用 page replacement algorithm 从内存中移除一个页以腾出空间。
- 加载页 − OS 从磁盘读取所需页并将其加载到物理内存中选定的帧。
- 更新页表 − OS 用新的帧号更新页表,并将 valid/invalid bit 设置为 valid。
- 重启指令 − 导致 page fault 的指令被重新启动,进程现在可以访问内存中的所需页。
下图展示了 OS 如何处理 page fault −
3. 页替换
如果物理内存中没有空闲帧可用,OS 将使用 page replacement algorithms 来决定从物理内存中移除哪个页,以为新页腾出空间。一些常见的页替换算法包括 −
- Least Recently Used (LRU) − LRU 算法移除最长时间未使用的页。
- First-In-First-Out (FIFO) − FIFO 算法移除内存中最旧的页。
- Optimal Page Replacement − 最优页替换算法移除未来最长时间不会使用的页(这是一个理论概念,在实践中无法实现)。
4. 抖动
Thrashing 发生在系统花费更多时间处理 page fault 而非执行实际进程时。如果进程大小大于可用物理内存,就会发生这种情况。也就是说,如果 RAM 容量较小,系统可能会不断将页在内存中交换进出,从而导致 thrashing。为了避免 thrashing,OS 将实施诸如调整多道程序设计度或使用 working set 模型等策略。
按需分页示例
假设一个程序包含四个页面:P1、P2、P3、P4。物理内存只有两个可用帧:F1、F2。最初,页面表如下所示 −
| 虚拟页面 | 物理帧 | 有效/无效位 | 磁盘位置 |
|---|---|---|---|
| P1 | - | Invalid | Disk1 |
| P2 | - | Invalid | Disk2 |
| P3 | - | Invalid | Disk3 |
| P4 | - | Invalid | Disk4 |
- 访问 P1 − CPU 尝试访问页面 P1 中的数据。页面表显示 P1 为 Invalid (I)。→ 发生 Page Fault。OS 从磁盘将 P1 加载到帧 F1 中。更新页面表:P1 现在为 Valid (V) 并映射到 F1。页面表中的物理帧列针对 P1 更新为 F1。
- 访问 P2 − CPU 尝试访问页面 P2 中的数据。页面表显示 P2 为 Invalid (I)。→ 发生 Page Fault。OS 从磁盘将 P2 加载到帧 F2 中。更新页面表:P2 现在为 Valid (V) 并映射到 F2。页面表中的物理帧列针对 P2 更新为 F2。
- 访问 P3 − CPU 尝试访问页面 P3 中的数据。页面表显示 P3 为 Invalid (I)。→ 发生 Page Fault。目前帧 F1 和 F2 均已被占用。因此 OS 使用页面替换算法(例如 LRU)来决定替换哪个页面。LRU 算法决定从 F1 中移除 P1。OS 从磁盘将 P3 写入帧 F1。更新页面表:P3 现在为 Valid (V) 并映射到 F1,P1 为 Invalid (I)。
- 访问 P2 − CPU 尝试访问页面 P2 中的数据。页面表显示 P2 为 Valid (V) 并映射到 F2。→ 无 Page Fault。CPU 直接从帧 F2 访问数据。
按需分页 vs 预分页
预分页与按需分页完全相反。在预分页中,操作系统在页面实际需要之前将多个页面加载到内存中。这是基于这样的假设:如果访问了一个页面,其附近的页面很快也会被访问。
我们已将 按需分页 和 预分页 的区别制成表格以便更好地理解 −
| 方面 | Demand Paging | Pre Paging |
|---|---|---|
| 定义 | 页面仅在需要时(按需)加载到内存中。 | 多个页面在实际需要之前加载到内存中。 |
| Page Faults | 由于页面仅在访问时加载,可能发生更多 page faults。 | 预期 page faults 较少,因为预加载了多个页面,从而减少访问未加载页面的机会。 |
| 内存使用 | 内存使用更高效。 | 内存效率低。这会导致内存空间浪费。 |
| 性能 | 由于频繁的 page faults 和磁盘 I/O 操作,可能导致性能较慢。 | 由于无 page faults,性能得到改善。 |
| 复杂度 | 易于实现 | 实现更复杂,因为需要预测未来的页面访问。 |
结论
Demand paging 是一种用于优化操作系统分页的内存管理技术。在按需分页中,页面仅在需要时加载到内存中。它有助于减少内存使用并提高整体系统性能。按需分页的主要缺点是增加 page faults 的可能性、性能较慢以及抖动(thrashing)。然而,由于其在内存管理方面的效率,它仍然被现代操作系统广泛使用。