请求分页存储系统是在纯分页基础上引入请求调页和页面置换机制而形成的虚拟存储系统,允许程序部分加载到内存,其余按需调入。其核心基础包括:
-
页表扩展:在基本页表中增加:
- 状态位(有效位):标识页面是否在内存。
- 访问字段:记录页面的访问频率或时间,用于置换算法。
- 修改位(脏位):判断页面是否被修改,决定是否写回磁盘。
- 辅存地址:记录页面在外存(如硬盘)中的位置,便于调入。
-
地址变换机构增强:MMU(内存管理单元)在地址转换时若发现页表项状态位为“不在内存”,则触发缺页中断,交由操作系统从外存调入所需页面。
-
缺页中断处理机制:操作系统负责将所需页面从外存调入内存,可能还需通过页面置换算法(如LRU、FIFO)腾出内存空间。
缺页中断的三大特点(与一般中断对比):
| 对比维度 | 缺页中断 | 一般中断 |
|---|---|---|
| 产生时机 | 指令执行期间发生 | 指令执行结束后、下条指令开始前 |
| 返回点 | 返回被中断指令的起始处重执行 | 返回下一条指令继续执行 |
| 触发次数 | 一条指令可能引发多次缺页中断 | 通常一条指令最多触发一次中断 |
例如:一条
COPY指令复制大量数据,若涉及多个不在内存的页面,则每访问一个缺失页都会中断一次。
【例 4.10】分析详解:
COPY指令本身跨两个页面 → 访问该指令需调入 2 个页面。- 源地址 A 跨两个页面且都不在内存 → 需调入 2 个页面。
- 目标地址 B 跨两个页面且都不在内存 → 需调入 2 个页面。
- 总共涉及 6 个页面?但注意题目说明是“指令所在页”作为一个逻辑单位,实际计算中常将指令首次访问视为一页触发。
然而根据题意合理理解:
- COPY 指令所在的代码段跨越2页 → 取指过程可能触发2次缺页;
- 但通常认为执行该指令时仅因取指产生一次页面请求(若两页均缺),不过更严谨的是:只要访问了不同页且缺失,就各算一次。
但标准解析中常简化为:
- 指令页:1 次(或2次,视情况)
- A 的两个数据页:2 次
- B 的两个数据页:2 次
若所有5个独立页都未在内存(即指令页算1个逻辑页,尽管跨物理页),则共触发 5 次缺页中断。
✅ 因此答案为:5 次缺页中断
补充背景总结:
请求分页是现代操作系统实现虚拟内存的主要方式之一,它通过以下机制提升内存利用率:
- 部分装入:程序运行初期只加载必要页面。
- 按需调页:访问到不在内存的页面时才调入。
- 页面置换:内存不足时将不常用页面换出到外存。
这使得程序可以运行在物理内存小于其总大小的情况下,极大提升了多道程序设计的能力和系统吞吐量。
# 简化的缺页中断模拟逻辑示意
page_fault_count = 0
def access_page(page_number, page_table):
global page_fault_count
if not page_table[page_number].valid:
print(f"缺页中断:页面 {page_number} 不在内存,正在调入...")
load_page_from_disk(page_number)
page_fault_count += 1
return "访问成功"
def load_page_from_disk(page_num):
# 模拟从磁盘加载页面到内存
page_table[page_num].frame = allocate_frame()
page_table[page_num].valid = True
在请求分页系统中,为了支持虚拟内存管理,页表在基本的页号到物理页框号映射的基础上,新增了多个关键字段,用于实现请求调页和页面置换。主要新增字段及其作用如下:
-
状态位(有效位,Valid/Presence Bit)
- 作用:标识该页是否已加载到内存。
- 取值说明:
- 1:页面在内存中,可直接访问。
- 0:页面不在内存,访问时将触发缺页中断。
- 用途:地址变换时判断是否需要调页。
-
访问字段(Access Bit / Reference Bit)
- 作用:记录该页面最近是否被访问过。
- 更新机制:每次对该页进行读或写操作时由硬件置位。
- 用途:供页面置换算法使用,如NRU(最近未使用)、**LFU(最不经常使用)**等。
-
修改位(脏位,Dirty Bit)
- 作用:标识该页面在调入内存后是否被修改过。
- 取值说明:
- 1:页面被修改,换出时需写回外存。
- 0:页面未被修改,可直接释放,无需写回。
- 用途:减少不必要的磁盘写操作,提高性能。
-
辅存地址(外存地址,Disk Address / Secondary Storage Address)
- 作用:记录该页面在外存(如交换空间或页面文件)中的存储位置。
- 用途:当发生缺页中断时,操作系统根据此地址从磁盘读取页面内容到内存。
-
保护位(Protection Bits,可选)
- 作用:定义页面的访问权限(如只读、可写、可执行)。
- 用途:防止非法访问,增强系统安全性。
-
缓存控制位(Cache Control Bits,可选)
- 作用:控制该页是否允许被缓存(用于特殊内存区域,如设备映射区)。
- 用途:优化I/O性能或保证一致性。
示例页表项结构(简化)
| 字段 | 含义说明 |
|---|---|
| 页框号 | 物理内存中的页框编号 |
| 状态位 | 是否在内存中(0/1) |
| 访问字段 | 最近是否被访问 |
| 修改位 | 是否被修改 |
| 辅存地址 | 外存中的起始地址 |
| 保护位 | 读/写/执行权限 |
| 缓存控制 | 是否启用缓存 |
这些扩展字段使得操作系统能够高效地管理虚拟内存,实现按需加载、页面替换和内外存数据一致性维护。
# 模拟一个页表项的数据结构
class PageTableEntry:
def __init__(self, disk_addr):
self.frame_number = None # 物理页框号
self.valid = False # 状态位:是否在内存
self.referenced = False # 访问字段:是否被访问
self.dirty = False # 修改位:是否被修改
self.disk_address = disk_addr # 辅存地址
self.protection = "RW" # 保护位:读写权限
def mark_accessed(self):
self.referenced = True
def mark_modified(self):
self.dirty = True
self.mark_accessed()



被折叠的 条评论
为什么被折叠?



