说明:本文为个人学习笔记,内容参考王道《操作系统》网课与配套讲义,按个人理解整理总结,仅用于学习交流,如有疏漏欢迎指正。

摘要

本文整理操作系统内存管理中三类经典机制与考点:

  • 基本分页存储管理:页表、地址变换、TLB、两级页表
  • 基本分段存储管理:段表、越界检查、分段与分页对比
  • 段页式管理方式:分段 + 分页结合后的地址转换

一、基本分页存储管理

1. 概念

将内存空间分为一个个大小相等的分区,每个分区称为一个 “页框”(页框 = 页帧 = 内存块 = 物理块 = 物理页面)。

将进程的逻辑地址空间也分为与页框大小相等的一个个部分,每个部分称为 “页”/“页面”

  • 每个页面有一个编号,称为 页号(从 0 开始)
  • 操作系统以页框为单位为进程分配内存
  • 进程的各页面与内存页框存在映射关系
  • 各页面不必连续存放,可装入不相邻页框中(离散分配)

为了知道进程的每个页面在内存中存放的位置,操作系统要为每个进程建立一张页表(通常存放在 PCB 中):

  • 一个进程对应一个页表
  • 进程的每个页面对应一个页表项
  • 每个页表项由 “页号” 和 “块号” 组成(逻辑概念)
  • 页表记录页号与内存块号(页框号)的映射关系
  • 每个页表项的长度是一样的

1.1 每个页表项占多少字节?

页表项逻辑上分为页号和块号,但通常只有 块号(以及控制位) 真正占存储空间;页号可以隐含(类比数组下标)。

注意:页表记录的是 内存块号,而不是内存块的起始地址。
j 号内存块的起始地址 = j × 内存块大小


2. 地址转换

2.1 连续存储(对比理解)

当进程在内存中连续存储时,重定位寄存器记录进程在内存中的起始位置,则:

物理地址 = 逻辑地址 + 起始位置

2.2 分页存储下的地址转换

当使用分页存储时,若要访问逻辑地址 A

  • 确定逻辑地址 A 对应的 页号 P
  • 查页表找到 P 号页面在内存中的起始位置(通过页框号计算)
  • 确定逻辑地址 A页内偏移量 W

因此:

逻辑地址 A 对应的物理地址 = P 号页面在内存中的起始地址 + 页内偏移量 W

手算(十进制)常用公式:

  • P = A / L(取整数部分)
  • W = A % L(取余数)

其中 L 为页面大小。

当页面大小是 2 的整数幂时,硬件可直接通过二进制位切分得到页号与页内偏移,从而无需除法运算:

同样可以快速得到物理地址(拼接/计算):

2.3 总结:页面大小刚好是 2 的整数幂有什么好处?

逻辑地址拆分更加迅速
若每页大小为 2^k(如 2KB),逻辑地址的低 k 位为页内偏移量,其余为页号。硬件可直接位切分,无需除法运算,从而更快。

物理地址计算更加迅速
页号查页表得到页框号后,将页框号与页内偏移量拼接即可形成物理地址(或用 E = b×L + W 计算)。


3. 页表寄存器(PTR)

通常系统中有一个 页表寄存器 PTR,存放:

  • 页表在内存中的起始地址 F
  • 页表长度 M

当进程未执行时,页表始址与页表长度放在 PCB 中;当进程被调度执行时,操作系统把它们放到 PTR 中。


4. 基本地址变换机构(不含 TLB)

设页面大小为 L,逻辑地址 A 到物理地址 E 的变换过程:

  1. 计算页号 P 与页内偏移量 W
  • 手算:P = A / LW = A % L
  • 实际机器:硬件按固定地址结构快速拆分
  1. 比较页号 P 与页表长度 M
    P ≥ M → 越界中断,否则继续。

注意:页号从 0 开始,因此当 P = M 时也越界。

  1. 计算页表项地址并取出块号 b
    页号 P 对应页表项地址:
  • 页表项地址 = F + P × 页表项长度

取出该页表项内容 b(页框号/块号)。

区分三个概念:

  • 页表长度:页表项个数(= 进程页数)
  • 页表项长度:每个页表项占用的存储空间
  • 页面大小:每个页面/页框占用的存储空间
  1. 计算物理地址并访存
  • E = b × L + W
    用物理地址 E 访存。

4.1 例题


5. 具有快表(TLB)的地址变换机构

5.1 快表(TLB)

快表,又称 联想寄存器(TLB,Translation Lookaside Buffer),是一种访问速度比内存快很多的高速缓存(TLB 不是内存),用来存放最近访问的页表项的副本,加速地址变换。

  • 内存中的页表常称为 慢表
  • 成本高 → TLB 容量小,不能放下整张页表
  • 因此形成 “TLB(快)+ 页表(慢)” 的多级结构兼顾效率与成本

TLB 与普通 Cache 的区别

  • TLB:只保存页表项副本(地址映射)
  • Cache:可缓存指令/数据等多种内容

5.2 引入快表后的地址变换过程

  1. CPU 给出逻辑地址,硬件算得页号、页内偏移量。
  2. 页号与快表中所有页号并行比较。
  • 若快表命中
    直接从 TLB 取出页框号,和页内偏移拼接得到物理地址,访问目标单元。
    仅需一次访存(访问数据/指令本身)。

  • 若快表未命中
    需要访问内存页表取得页框号,再得到物理地址访问目标单元;并把该页表项写入 TLB(若满则替换)。
    需要两次访存(页表一次 + 数据一次)。

5.3 引入快表后查询速度得到提升的例子


6. 局部性原理

  • 时间局部性:执行某条指令后不久可能再次执行;访问某数据后不久可能再次访问(循环常见)。
  • 空间局部性:访问某存储单元后,其附近单元不久可能被访问(连续存放/顺序访问常见)。

7. 两级页表

7.1 单级页表存在的问题

  • 页表必须连续存放:页表很大时需要占用很多连续页框(与离散分配思想相悖)。
  • 没必要让整个页表常驻内存:进程一段时间内可能只访问少数页面。

7.2 原理

两级页表为解决单级页表内存浪费连续空间占用过大问题而设计。

  • 第一级页表:页目录表,记录二级页表的内存块号,必须常驻内存
  • 第二级页表:页表,记录实际页面的内存块号,可按需装入

7.3 优势

  • 节约内存空间:按需装入用到的二级页表
  • 无需连续内存:二级页表分散占用不同页框,彼此无需连续
  • 支持按需置换:未访问的二级页表可换出外存,需要时再调入

7.4 细节

若采用多级页表机制,则各级页表的大小通常不应超过一个页面。


二、基本分段存储管理

1. 分段

分段系统将用户进程逻辑空间划分为大小不等的段。

逻辑地址结构:段号(段名) + 段内地址(段内偏移量)

  • 段号位数:决定每个进程最多可分多少段
  • 段内地址位数:决定每段最大长度

2. 段表


3. 地址变换机构

  1. 从逻辑地址中取出段号 S 和段内偏移 W
  2. 判断段号是否越界:若 S ≥ 段表长度 M → 越界中断。
  3. 查段表项,得到段长 C:若 W ≥ C → 越界中断。
  4. 取段基址 b:计算物理地址 E = b + W,并访存。


4. 分页与分段的对比

  1. 单位与可见性
  • 页:信息的物理单位,提高内存利用率;分页是系统行为,对用户不可见
  • 段:信息的逻辑单位,更满足用户需求;分段对用户可见
  1. 大小
  • 页大小固定,由系统决定
  • 段长度不固定,由程序逻辑决定
  1. 地址空间维度
  • 分页地址空间一维
  • 分段必须显式给段号+偏移,地址空间二维
  1. 共享与保护
    分段更容易实现信息共享与保护。纯代码/可重入代码可共享,可修改代码通常不可共享。

三、段页式管理方式

1. 分段 & 分页结合

段页式系统中:进程地址空间先分段,每段再分页;内存仍按页框管理并以页框为单位分配。


2. 地址转换


小结

  • 分页:页表映射,离散分配,提高内存利用率
  • 分段:段表(基址+段长),逻辑清晰,便于共享保护
  • 段页式:段表 + 段内页表,兼顾逻辑性与效率