参考视频:王道计算机考研 操作系统_哔哩哔哩_bilibili
参考书籍:左万利《计算机操作系统教程(第4版)》
目录
第三章 内存管理
四、非连续分配管理方式
(书本)界地址存储管理方式(连续分配管理)要求一个进程占有内存空间中的一个连续区域,因而采用动态异长存储分配方法可能产生碎片。相反,页式(paging,也称分页)存储管理方式允许一个进程占有内存空间中的多个连续区域,而且这些区域的长度相同,因而采用静态等长存储分配方法,不会产生碎片。
为防止碎片的产生,而且不使用紧凑技术,提高内存利用率。
1.页式/分页存储管理
将内存空间和进程空间都进行更细致的等长划分。进程存入内存也可以不按顺序存放。
1.1 内存空间划分
内存空间被静态划分为若干个等长区域,每个区域称为一个物理页框(page frame),每个页框通常有 2^𝑖(𝑖 是正整数)个单元(上图的每个页框4KB大小 )。将每一页从0开始依次编址,称为页内地址(页内偏移量)。
设内存的容量为 2^n B,则共有 2^(n-𝑖)个页框。所有页框从0开始依次编号,称为页框号。易见下图,第 𝑘 个页框的起始地址(即首址)为 𝑘×2^𝑖 。
【实际上,将页框号(n-𝑖 位)作为高位,页内地址(𝑖 位)作为低位,即可得到物理地址】
1.2 进程空间划分
进程空间也被静态地划分为若干个等长的区域,每个区域称为一个逻辑页面,其长度与页框的长度相同即共有 2^𝑖(𝑖 是正整数)个单元。将每一页从0开始依次编址,称为页内地址。
设进程共有 𝑙 个逻辑页面,将其由0开始依次编号,称为逻辑页号。易见下图,第 𝑘 个逻辑页面的起始地址(即首址)为 𝑘×2^𝑖 。
【实际上,将逻辑页号(n-𝑖 位)作为高位,页内地址(𝑖 位)作为低位,即可得到逻辑地址】
1.3 进程空间与内存空间的对应关系
当进程运行时,需要将它的各个逻辑页面保存到物理页框中。进程的每一个逻辑页面是连续的,但是这些逻辑页面所对应的物理页框不一定连续。
所以需要一个表来描述:逻辑页面0分配到第15个页框,逻辑页面1分配到第22个页框......
1.4 所需表目
① 页表。记录进程的逻辑页面与内存页框之间的对应关系。
- 每个进程都有一个页表(页号,页框号),每个页表项的长度是相同的。
- 由于逻辑页号是连续的,因而可将其省略,是“隐含”的。
② 总页表。记录页框的使用情况(空闲和占有)。
补充——为什么说每个页表项长度相同,页号是可以省略的?
答:给出起始地址以及页表项长度就足以算出各个页号对应的页表项存放的位置。
一个页表项3B,如果进程有n个页面,则进程的页表总共会占 3×n个字节。
1.5 所需寄存器
地址映射将逻辑页号转换为页框号,为此需要:
- 首先由进程控制块(PCB)中找到页表的起始地址及长度;
- 然后由逻辑页号查页表找到页框号。
由于PCB和页表都保存在内存中,所以每次地址变换都需要访问两次内存,速度降低50%。为解决这个问题,硬件一般提供3组寄存器:
① 页表首址寄存器:基址寄存器里存放了页表的首地址。在一个进程被低级调度程序选中并投入运行之前,系统将其页表首址由PCB中取出并送入该寄存器。
② 页表长度寄存器:限长寄存器里存放了页表的长度。在一个进程被低级调度程序选中并投入运行之前,系统将其页表首址由PCB中取出并送入该寄存器。
③ 一组联想寄存器——快表(translation lookaside buffer,TLB):用于保存正在运行进程的页表中的部分项目。(最近使用的页表项都会存入快表)
- 较页表而言,造价高、数量少、长度短、速度快。
- 根据逻辑页号,先查找快表,找到了则直接转换出物理地址;没找到就进内存找页表,找到后顺便放入快表,便于下次查找。
- 快表满了就按照置换算法淘汰掉一个。
1.6 基本地址变换机构
PCB中取出页表地址和长度放入页表寄存器。
取页表,判越界,转物理
1.7 具有快表的地址变换机构
局部性原理:
时间局部性:若执行程序中的某条指令,不就后很可能再次执行;若某数据被访问过,不就后很可能再次访问。
空间局部性:一旦访问某个存储单元,不久后,其附近的存储单元也很可能被访问。
设页面大小L,页号P,页内地址W,对应页框号b,页表首址F,页表长度M。
逻辑地址(P, W) ==> 物理地址(b, W):
① 由指令产生逻辑地址A (P, W) 。(P=A/L,W=A%L)
② 由逻辑页号P查找快表得到页框号b。
如果找不到:
(a)由页号 P 与页表长度 M 比较是否满足 0 ≤ P ≤ M-1(0 ≤ P<M)。若不满足,则越界中断。
(b)由页号 P 与页表首址 F 查页表得到页框号 b。
(c)parbegin(并行运行)
将页框号 b 与页内地址 W 合并得到物理地址E (b,W)。【→访问目标单元】
将 (P,W) 送入快表中。如果此时快表已满,按置换算法(虚拟存储管理那节)淘汰一个。
③ 命中,则直接将页框号 b 与页内地址 W 合并得到物理地址E (b,W)。【→访问目标单元】
1.8 有效访问时间
程序执行一个指令,从指令执行开始,由逻辑地址转换为物理地址,并且访问这个地址的过程,这段时间叫有效访问时间(effective access time,EAT)。
EAT = 快表命中率 ×(快表访问时间 + 内存访问时间)+
(1 - 快表命中率)×(快表访问时间 + 2 × 内存访问时间)ns
(注:两个内存访问时间分别为访问页表的时间和访问目标内存单元的时间)
1.9 二级、多级页表
背景:内存空间成倍增长,进程虚拟空间成倍增加。单级页表需要很大连续内存空间。
例如:32位进程地址空间,页长占12位(4KB),则一个进程最多可以拥有 2^20个页面。
于是就有两个问题:
第一、系统需要提供长度为2^20的连续页表区域,这很困难。
第二、完全不需要整个页表全部常驻内存。
解决策略:二级或多级页表。
将 2^20 页表分为 2^10 × 2^10 两级,一级称为外页表(页目录表、顶级页表),另一级称为内页表。长度都在 2^10 以内。外页表中记录了相应内页表在内存中的起始地址,即内页表存放位置。
(第一次访问内存)① 从PCB中得到外页表的存储位置,取出外页表;
(第二次访问内存)② 利用一级页号从外页表中取出内页表(二级页表);
(第三次访问内存)③ 再用二级页号和页内偏移量在内页表中找到最终要访问的页框号。
显然,多级页表会减缓地址映射的速度,但是通过快表仍然可以将效率保存在合理的范围内。
2.段式/分段存储管理
在页式存储中,分页对于用户是透明的,系统负责,用户不知道是否已经分页,一个进程由若干个页构成,所有页的长度相同。
在段式存储中,分段对于用户是可见的,用户需要显式给出段名,一个进程由若干个段构成,各个段的长度可以不同,一个段恰好对应一个程序单位。
2.1 内存空间划分
内存空间动态地划分为若干个长度各异的区域(动态异长),每个区域称为一个物理段,每个物理段中的所有单元由0开始依次编址,称为段内地址。
内存中的物理地址 = 段首址 + 段内地址(段内偏移)
2.2 进程空间划分
进程空间被静态地划分为若干个长度各异的区域(静态异长),每个区域称为一个逻辑段。一个逻辑段通常对应一个程序单位,例如一个主程序、一个子程序、一个数据区等。
逻辑地址 = 段号 + 段内地址
2.3 进程空间与内存空间的对应关系
所有逻辑段存放在内存中不同的连续区域里。主段 MAIN 存储在 80k 开始的 7k 大小的l连续内存空间上,X段存储在 120k 开始的 3k 大小的连续内存空间上,D段存储在 40k 开始的 6k 大小的连续内存空间上。
2.4 所需表目
① 段表。每个进程都有一个段表,用于记录段号与段首址之间的关系。段号连续,可隐藏。由于每个段的段长可能不同,所以需要记录段长。因此每个段表项包含段长和段首址(基址)。
与分页(一维:页框号)不同,分段的地址空间是二维的。
② 空闲表。用于记录并管理内存中的空闲区域。管理算法见动态分区分配(首次适应......)。
2.5 所需寄存器
提供寄存器的原因同页式管理(访问两次内存,降低访问速度)。
① 段表首址寄存器。进程调度运行前,从PCB中取出段表首址放入该寄存器。
② 段表长度寄存器。进程调度运行前,从PCB中取出段表长度放入该寄存器。
③ 一组联想寄存器(快表)。
2.6 地址映射(带快表)
设段号s,段内地址d;段表首址b,段表长度𝑙;段首址b',段长𝑙'。
逻辑地址(s,d) ==> 物理地址(b'+d):
① 由指令产生逻辑地址 (s,d)。
② 由段号s查找快表得到段首址 b' 和段长 𝑙'。
如果找不到:
(a)将段号 s 与段表长度 𝑙 相比较,不满足 0 ≤ s ≤ 𝑙-1,则越界中断。
(b)由段号 s 与段表首址 b 查找内存段表,得到段首址和段长 (b',𝑙')。
(c)parbegin
由段首址 b' 和段内地址 d 相加得到物理地址 b' + d。
将 (s,b',𝑙') 送入快表。如果此时快表已满,按置换算法淘汰一个。
parend
③ 将段内地址 d 与段长 𝑙' 相比较,不满足 0 ≤ d ≤ 𝑙'-1,则越界中断。(与页表不同之处)
④ 由段首地址 b' 和段内地址 d 相加得到物理地址 b' + d。
补充:
2.7 段的共享(段比页的优点)
进程A和进程B中都存在1号代码段,因此可以使两个进程的两个段表中都存在一项表项,共用内存中的一块区域。
2.8 段的保护
若进行分页,显然,一个页框中有不同的代码段。假设只有绿色部分才可以被进程A共享,那么进程A访问哪个页都不合理。
进程对于共享段的访问往往需要加上某种限制。为此需要增加“访问权限”一栏,而不同进程对同一共享段有不同的权限,因此将其放入段表中。
3.段页式存储管理
页式存储管理解决了外部碎片问题,段式存储管理便于实现共享。取二者之长,避二者之短,需将页式存储管理与段式存储管理结合,形成段页式(segmentation with paging)存储管理方式。
3.1 内存空间划分
与页式存储一样,静态等长区域,每个区域 2^𝑖 个单元,称为一个页框。
物理地址 = (页框号,页内地址)
3.2 进程空间划分
按段式存储的方法,一个进程静态划分为若干个长度不同的段,称为逻辑段;按页式存储的方法,再对段进一步划分,每一个段静态划分为若干个长度相同的页,称为逻辑页面。
逻辑地址 = (段号,逻辑页号,页内地址)
注:“分段”对用户可见,“分页”对用户不可见,段内地址由系统自动划分为页号和页内地址。因此,段页式管理的地址结构是二维的。
位数的含义:
段号16位,每个进程最多有 2^16 = 64K个段;页号4位,每个段最多有 2^4 = 16页;
页内偏移12位,每个页面/每个页框大小为 2^12 = 4 KB
3.3 进程空间与内存空间的对应关系
进程空间内每一段内的每一个逻辑页面都对应内存空间的一个页框。同一段内的逻辑页面是连续的,而逻辑页面对应的(内存中的)页框未必连续。
3.4 所需表目
① 段表。每个进程有一个,记录段号、页表长度与页表首址。
② 页表。每个段有一个,一个进程有多个,记录逻辑页号与页框号。
③ 总页表。即位图,用于记录和管理内存页面。管理算法见动态分区分配(首次适应......)。
3.5 所需寄存器
① 段表首址寄存器。段表基址。
② 段表长度寄存器。段表长度。
③ 一组联想寄存器(快表)。段号、逻辑页号、页框号(页架号)。
3.6 地址映射(带快表)
逻辑地址(s,p,d) ==> 物理地址(f,d):
① 由指令产生逻辑地址 (s,p,d)。
② 由段号和逻辑页号 (s,p) 查找快表得到页框号 f。
如果找不到:
(a)将段号 s 与段表长度 𝑙 相比较,不满足 0 ≤ s ≤ 𝑙-1,则越界中断。
(b)由段号 s 与段表首址 b 查找内存段表,得到段首址和段长 (b',𝑙')。
(c)将逻辑页号 p 与页表长度 𝑙' 比较,不满足 0 ≤ p ≤ 𝑙'-1,则越界中断。
(d)由逻辑页号 p 与页表首址 b' 查找页表得到页框号 f。
(e)parbegin
由页框号 f 和段内地址 d 合并得到物理地址 (f,d)。
将 (s,p,f) 送入快表。如果此时快表已满,按置换算法淘汰一个。
parend
③ 由页框号 f 和段内地址 d 合并得到物理地址 (f,d)。
注:若没有快表,存在三次访存:取段表;取页表;访问目标内存单元。