【操作系统-内存】页面分配策略和页面置换算法
0 基本概念
- 驻留集:指请求分页存储管理中给进程分配的物理块(即页框)的集合。在采用了虚拟存储技术的系统中,驻留集大小一般小于进程的总大小。
【注】若驻留集太小,会导致缺页频繁,系统要花大量的时间来处理缺页,实际用于进程推进的时间很少;驻留集太大,又会导致多道程序并发度下降,资源利用率降低。所以应该选择一个合适的驻留集大小。
- 工作集:指在某段时间间隔里,进程实际访问页面的集合。
- 窗口尺寸:页面访问序列的集合,窗口尺寸有多大,访问序列中就有多少个页面。
【注 1】工作集和窗口尺寸的区别:
某进程的页面访问序列如下,窗口尺寸为 4。
(24,15,18,23),24,17,(18,24,18,17),17,15
括号表示窗口尺寸,则第一个窗口尺寸对应的工作集是 24,15,18,23,工作集为 4;第二个窗口尺寸对应的工作集是 18,24,17,工作集为 3。
【注 2】驻留集大小不能小于工作集大小,否则进程运行过程中将频繁缺页。
- 抖动:刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够,即驻留集太小)。
1 页面分配策略
1.1 页面分配的策略
- 固定分配:操作系统为每个进程分配一组固定数目的物理块,在进程运行期间不再改变。即,驻留集大小不变。
- 可变分配:先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少。即,驻留集大小可变。
1.2 页面置换的策略
- 局部置换:发生缺页时只能选进程自己的物理块进行置换。
- 全局置换:可以将操作系统保留的空闲物理块分配给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程。
【注】有些题目也把“置换”称为“淘汰”。
1.3 分配和置换的策略组合
策略组合 | 局部置换 | 全局置换 |
---|---|---|
固定分配 | 进程运行前就分配一定数量的物理块,缺页时只能换出进程自己的一页 | 此组合不存在,因为进程的物理块数是固定的,不能再申请或占用操作系统中的空闲物理块 |
可变分配 | 进程运行前就分配一定数量的物理块,缺页时只能换出进程自己的一页,系统根据发生缺页的频率来动态地增加或减少进程的物理块 | 进程运行前就分配一定数量的物理块,只要进程发生缺页,都将获得新的物理块 |
2 页面调入策略
2.1 页面调入的时机
策略 | 描述 |
---|---|
预调页策略 | 系统预测不久之后可能访问到的页面,将它们预先调入内存,主要用于进程的首次调入 |
请求调页策略 | 进程在运行期间发现缺页时才将所缺页面调入内存 |
2.2 页面调入的位置
- 对换:把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或者进程所需的程序或者数据换入。
【注 1】对换属于中级调度。
【注 2】如果对换是以整个进程为单位的,便称之为“整体对换”或“进程对换”,这种对换被广泛地应用于分时系统中,其目的是用来解决内存紧张的问题,进一步提高内存利用率;如果对换是以“页”或“段”为单位进行的,则分别称之为“页面对换”或“分段对换”,又统称为“部分对换”。
在具有对换功能的操作系统中,通常把磁盘空间(外存空间) 分为文件区和对换区两部分:
- 对换区:用于存放从内存换出的进程,读/写速度更快,采用连续分配方式。
- 文件区:用于存放文件,读/写速度更慢,采用离散分配方式。
情况 | 描述 |
---|---|
系统拥有足够的对换区空间 | 运行前将数据从文件区复制到对换区,之后所有页面调入、调出都是在内存和对换区进行 |
系统缺少足够的对换区空间 | 不会修改的数据每次都从文件区调入内存,会修改的数据调出对换区,需要时再调入对换区 |
UNIX 方式 | 运行前将数据从文件区调入内存,从内存调出的页面都写回对换区,再次使用时从对换区调入内存 |
3 页面置换算法
注意,页面置换策略一般用在虚拟内存管理中。在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。
各种页面置换算法的优缺点如下:
算法 | 优缺点 |
---|---|
最佳置换算法(OPT) | 缺页率最小,性能最好;但无法实现 |
先进先出置换算法(FIFO) | 实现简单;但性能很差,可能出现Belady异常 |
最近最久未使用置换算法(LRU) | 性能很好;但需要硬件支持,算法开销大(需要对页号进行排序) |
时钟置换算法(CLOCK) | 实现简单,算法开销小;但未考虑页面是否被修改过 |
改进型时钟置换算法(CLOCK) | 算法开销较小,性能不错 |
3.1 最佳置换算法(OPT)
- 思路:每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率。
最佳置换算法可以保证最低的缺页率,但实际上,只有在进程执行的过程中才能知道接下来会访问到的是哪个页面。操作系统无法提前预判页面访问序列。因此,最佳置换算法是无法实现的,详细的算法过程就不再写了。
3.2 先进先出置换算法(FIFO)
- 思路:每次选择淘汰的页面是最早进入内存的页面。
- 实现方法:把调入内存的页面根据调入的先后顺序排成一个队列,需要换出页面时选择队头页面即可。队列的最大长度取决于系统为进程分配了多少个内存块。
- Belady 异常:当为进程分配的物理块数增大时,缺页次数不减反增的异常现象。
【注 1】只有 FIFO 算法会产生 Belady 异常。另外,FIFO算法虽然实现简单,但是该算法与进程实际运行时的规律不适应,因为先进入的页面也有可能最经常被访问。
【注 2】FIFO 算法应比较“页面装入时刻”或“页面装入时间”,哪个页面的装入时刻最小就先置换哪个。
3.3 最近最久未使用置换算法(LRU)(重点)
- 思路:每次淘汰的页面是最近最久未使用的页面。
- 实现方法:赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间 t。当需要淘汰一个页面时,选择现有页面中 t 值最大的,即最近最久未使用的页面。
- 技巧:若需要淘汰页面,可以逆向检查访问序列。假设某进程分配了 n 个内存块,则逆向找到第 n 个不同且在内存中的页号,该页号就是要淘汰的页面。
【注】LRU 算法应比较“最近访问时间”或“最近访问时刻”,哪个页面的最近访问时间最小就先置换哪个。
例 1(基本原理和做题技巧,必看)
【例 1】假设系统为某进程分配了四个内存块,并考虑到有以下页面号引用串:
1, 8, 1, 7, 2, 7, 2, 8, 3, 8, 2, 1, 3, 1, 7, 1, 3
【解】(1)进程的内存块从空到满,还未发生缺页:
访问页面 | 1 | 8 | 1 | 7 | 2 | 7 | 2 | 8 |
---|---|---|---|---|---|---|---|---|
内存块 1 | 1 | 1 | 1 | 1 | ||||
内存块 2 | 8 | 8 | 8 | |||||
内存块 3 | 7 | 7 | ||||||
内存块 4 | 2 | |||||||
缺页 | √ | √ | √ | √ |
(2)页号 3 不存在,发生缺页,逆向检查访问序列,找到第 4 个不同且在内存中的页号,该页号就是要淘汰的页面:
(1, 8, 1, 7, 2, 7, 2, 8)--(从右往左找,第一个是 8,第二个是 2,第三个是 7,第四个是 2,因为前面已经重复出现,故不算数,第五个是 1,至此已找出四个不同且在内存中的页号)-->(1, 8, 1, 7, 2, 7, 2, 8)--> 此时已有四个不同的页号 8,2,7,1,逆向找到第 4 个不同的页号是 1,因此页号 1 被淘汰。
访问页面 | 3 | 8 | 2 |
---|---|---|---|
内存块 1 | 3 | ||
内存块 2 | 8 | ||
内存块 3 | 7 | ||
内存块 4 | 2 | ||
缺页 | √ |
(3)页号 1 不存在,发生缺页,逆向检查访问序列,找到第 4 个不同且在内存中的页号,该页号就是要淘汰的页面:
(1, 8, 1, 7, 2, 7, 2, 8, 3, 8, 2)--(从右往左找,第一个是 2,第二个是 8,第三个是 3,第四个是 8,因为前面已经重复出现,故不算数,第五个是 2,也不算数,第六个是 7,至此已找出四个不同且在内存中的页号)-->(1, 8, 1, 7, 2, 7, 2, 8, 3, 8, 2)--> 此时已有四个不同的页号 2,8,3,7,逆向找到第 4 个不同的页号是 7,因此页号 7 被淘汰。
访问页面 | 1 | 3 | 1 |
---|---|---|---|
内存块 1 | 3 | ||
内存块 2 | 8 | ||
内存块 3 | 1 | ||
内存块 4 | 2 | ||
缺页 | √ |
(4)页号 7 不存在,发生缺页,逆向检查访问序列,找到第 4 个不同且在内存中的页号,该页号就是要淘汰的页面:
(1, 8, 1, 7, 2, 7, 2, 8, 3, 8, 2, 1, 3, 1)--(从右往左找,第一个是 1,第二个是 3,第三个是 1,因为前面已经重复出现,故不算数,第四个是 2,第五个是 8,至此已找出四个不同且在内存中的页号)-->(1, 8, 1, 7, 2, 7, 2, 8, 3, 8, 2, 1, 3, 1)--> 此时已有四个不同的页号 1,3,2,8,逆向找到第 4 个不同的页号是 8,因此页号 8 被淘汰。
访问页面 | 7 | 1 | 3 |
---|---|---|---|
内存块 1 | 3 | ||
内存块 2 | 7 | ||
内存块 3 | 1 | ||
内存块 4 | 2 | ||
缺页 | √ |
(5)缺页率 = 7/17。
例 2(2015 真题,技巧秒杀)
【例 2】系统为某进程分配了 4 个页框,该进程已访问的页号序列为2,0,2,9,3,4,2,8,2,4,8,4,5。若进程要访问的下一页的页号为 7,依据 LRU 算法,应淘汰页的页号是( )
A. 4
B. 5
C. 8
D. 2
【解】很显然,页号 7 不存在,缺页需要置换。发生缺页时,逆向检查访问序列,找到第 4 个不同且在内存中的页号,该页号就是要淘汰的页面。
因此,(2,0,2,9,3,4,2,8,2,4,8,4,5)-->(从右往左找,第一个是 5,第二个是 4,第三个是 8,第四个是 2,第五个是 4,因为前面已经重复出现,故不算数,第五个是 2,至此已找出四个不同且在内存中的页号)-->(2,0,2,9,3,4,2,8,2,4,8,4,5)--> 此时已有四个不同的页号 2,4,8,5,逆向找到第 4 个不同的页号是 2,因此页号 2 被淘汰,选 D。
例 3(2019 真题)
【例 3】某系统釆用 LRU 页置换算法和局部置换策略,若系统为进程 P 预分配了 4 个页框,进程 P 访问页号的序列为 0, 1, 2, 7, 0, 5, 3, 5, 0, 2, 7, 6,则进程访问上述页的过程中,产生页置换的总次数是( )
A. 3
B. 4
C. 5
D. 6
【解】
(0, 1, 2, 7)一定缺页,但需要注意,一开始时进程页面为空,这四个是调入空白页中,所以不是页置换。此时进程页面为(0, 1, 2, 7)。
(0, 1, 2, 7, 0, 5)发生缺页,此时进程页面为(0, 1, 2, 7),按照技巧,替换页号 1,所以进程页面变为(0, 5, 2, 7)。
(0, 1, 2, 7, 0, 5, 3)发生缺页,此时进程页面为(0, 5, 2, 7),按照技巧,替换页号 2,所以进程页面变为(0, 5, 3, 7)。
(0, 1, 2, 7, 0, 5, 3, 5, 0, 2)发生缺页,此时进程页面为(0, 5, 3, 7),按照技巧,替换页号 7,所以进程页面变为(0, 5, 3, 2)。
(0, 1, 2, 7, 0, 5, 3, 5, 0, 2, 7)发生缺页,此时进程页面为(0, 5, 3, 2),按照技巧,替换页号 3,所以进程页面变为(0, 5, 7, 2)。
(0, 1, 2, 7, 0, 5, 3, 5, 0, 2, 7, 6)发生缺页,此时进程页面为(0, 5, 7, 2),按照技巧,替换页号 5,所以进程页面变为(0, 6, 7, 2)。
一共页置换 5 次,选 C。
【注 1】若题目改成“产生缺页的总次数”,则应该答 9 次。
【注 2】若题目改成“产生中断的总次数”,则也应该答 9 次,因为缺页会引发缺页中断。
3.4 时钟置换算法(CLOCK)(重点)
又称最近未用算法(NRU,Not Recently Used)。
实现方法:
- 为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。
- 当某页被访问时,其访问位置为 1,否则保持为 0。
- 当需要淘汰一个页面时,只需检查页的访问位。如果是 0,就选择该页换出;如果是 1,则将它置为 0,暂不换出,继续检查下一个页面。
- 若第一轮扫描中所有页面都是 1,则将这些页面的访问位依次置为 0 后,再进行第二轮扫描。
【注】第二轮扫描中一定会有访问位为 0 的页面,因此简单的 CLOCK 算法选择一个淘汰页面最多会经过两轮扫描。
例 1(基本原理)
【例 1】假设系统为某进程分配了五个内存块,并考虑到有以下页面号引用串:
1, 3, 4, 2, 5, 6, 3, 5, 7
【解】(页号后面的括号均表示访问位)
(1)前五个页访问后,进程页面(1(1), 3(1), 4(1), 2(1), 5(1))。
(2)访问第六个页的页号为 6,缺页,此时需要置换某页。
指针指向进程页面的第一个页号 1,其访问位是 1,则将它置为 0,暂不换出,进程页面(1(0), 3(1), 4(1), 2(1), 5(1)),继续检查下一个页面。
指针指向进程页面的第二个页号 3,其访问位是 1,则将它置为 0,暂不换出,进程页面(1(0), 3(0), 4(1), 2(1), 5(1)),继续检查下一个页面。
指针指向进程页面的第三个页号 4,其访问位是 1,则将它置为 0,暂不换出,进程页面(1(0), 3(0), 4(0), 2(1), 5(1)),继续检查下一个页面。
指针指向进程页面的第四个页号 2,其访问位是 1,则将它置为 0,暂不换出,进程页面(1(0), 3(0), 4(0), 2(0), 5(1)),继续检查下一个页面。
指针指向进程页面的第五个页号 5,其访问位是 1,则将它置为 0,暂不换出,进程页面(1(0), 3(0), 4(1), 2(0), 5(0)),继续检查下一个页面。
指针重新指向进程页面的第一个页号 1,其访问位是 0,选择该页换出,此时进程页面(6(1), 3(0), 4(0), 2(0), 5(0))。
(3)访问第七个页的页号为 3,在进程页面中,此时进程页面(6(1), 3(1), 4(0), 2(0), 5(0))。
(4)访问第八个页的页号为 5,在进程页面中,此时进程页面(6(1), 3(1), 4(0), 2(0), 5(1))。
(5)访问第九个页的页号为 7,缺页,此时需要置换某页。
指针指向进程页面的第一个页号 6,其访问位是 1,则将它置为 0,暂不换出,进程页面(6(0), 3(1), 4(0), 2(0), 5(1)),继续检查下一个页面。
指针指向进程页面的第二个页号 3,其访问位是 1,则将它置为 0,暂不换出,进程页面(6(0), 3(0), 4(0), 2(0), 5(1)),继续检查下一个页面。
指针指向进程页面的第三个页号 4,其访问位是 0,选择该页换出,此时进程页面(6(0), 3(0), 7(1), 2(0), 5(1))。
例 2(技巧)
【例 2】假设系统为某进程分配了五个内存块,并进程页面的情况如下(后面的括号表示访问位):
进程 A:1(1), 3(1), 4(0), 2(0), 5(1)
进程 B:1(1), 3(1), 4(1), 2(1), 5(1)
对于进程 A 和进程 B,均需要置换某页,假设指针均指向第一个页面,则需要置换哪一页?
【解】对于进程 A,找到第一个访问位为 0 的页号,即页号 4 会被置换。
对于进程 B,由于访问位全部都是 1,因此第一个页号即页号 1 会被置换。
【注】访问位部分为“0”选择第一个为“0”的页号,访问位全为“1”选择第一个页号。
3.5 改进型时钟置换算法(CLOCK)(重点)
用 (访问位,修改位) 的形式表示各页面状态。
算法规则:
- 将所有可能被置换的页面排成一个循环队列。
- 第一轮:从当前位置开始扫描到第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。
- 第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。本轮将所有扫描过的帧访问位设为 0。
- 第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。
- 第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。
【注 1】由于第二轮已将所有帧的访问位设为 0,因此经过第三轮、第四轮扫描一定会有一个帧被选中,因此改进型CLOCK置换算法选择一个淘汰页面最多会进行四轮扫描。
【注 2】该算法仅修改访问位,不修改修改位。
【注 3】该算法的本质是将页面划分为了四个优先级,优先级越大,被置换的可能性就越小。如下:
- (0,0):第一优先级,最近没访问,且没修改的页面。
- (0,1):第二优先级,最近没访问,但修改过的页面。
- (1,0):第三优先级:最近访问过,但没修改的页面。
- (1,1):第四优先级:最近访问过,且修改过的页面。
所以算法规则又可以写为:
- 第一轮:淘汰(0, 0),若没找到就进行第二轮。
- 第二轮:淘汰(0, 1),若没找到就进行第三轮。
- 第三轮:淘汰(1, 0),若没找到就进行第四轮。
- 第四轮:淘汰(1, 1)。
3.6 综合例题
例 1(基本原理,必看)
【例 1】一进程已分配到 4 个页帧,见下表(编号为十进制,从 0 开始)。当进程访问第 4 页时,产生缺页中断,请分别用 FIFO(先进先出)、LRU(最近最少使用)、NRU(最近不用)或 CLOCK 算法、改进型 NRU(最近不用)或 CLOCK 算法,决定缺页中断服务程序选择换出的页面。(假设置换的时间为 170)
虚拟页号 | 页帧(页框、物理块) | 装入时间 | 最近访问时间 | 访问位 | 修改位 |
---|---|---|---|---|---|
2 | 0 | 60 | 161 | 0 | 1 |
1 | 1 | 130 | 160 | 0 | 0 |
0 | 2 | 26 | 162 | 1 | 0 |
3 | 3 | 20 | 163 | 1 | 1 |
【解】(1)FIFO(先进先出):装入时间最小的为页号 3,因此置换页号 3 的页面。此时页框 3 中原来存放的页面 3 的内容被换成页面 4 的内容,置换后的情况如下:
虚拟页号 | 页帧(页框、物理块) | 装入时间 | 最近访问时间 | 访问位 | 修改位 |
---|---|---|---|---|---|
2 | 0 | 60 | 161 | 0 | 1 |
1 | 1 | 130 | 160 | 0 | 0 |
0 | 2 | 26 | 162 | 1 | 0 |
4 | 3 | 170 | 170 | 1 | 0 |
(2)LRU(最近最少使用):最近访问时间最小的为页号 1,因此置换页号 1 的页面。此时页框 1 中原来存放的页面 1 的内容被换成页面 4 的内容,置换后的情况如下:
虚拟页号 | 页帧(页框、物理块) | 装入时间 | 最近访问时间 | 访问位 | 修改位 |
---|---|---|---|---|---|
2 | 0 | 60 | 161 | 0 | 1 |
4 | 1 | 170 | 170 | 1 | 0 |
0 | 2 | 26 | 162 | 1 | 0 |
3 | 3 | 20 | 163 | 1 | 1 |
(3)NRU(最近不用)或 CLOCK 算法:第一个访问位为 0 的页面是页号 2,因此置换页号 2 的页面。此时页框 0 中原来存放的页面 2 的内容被换成页面 4 的内容,置换后的情况如下:
虚拟页号 | 页帧(页框、物理块) | 装入时间 | 最近访问时间 | 访问位 | 修改位 |
---|---|---|---|---|---|
4 | 0 | 170 | 170 | 1 | 0 |
1 | 1 | 130 | 160 | 0 | 0 |
0 | 2 | 26 | 162 | 1 | 0 |
3 | 3 | 20 | 163 | 1 | 1 |
(4)改进型 NRU(最近不用)或 CLOCK 算法:找到第一个访问位和修改位都为 0 的页面,为页号 1,因此置换页号 1 的页面。此时页框 1 中原来存放的页面 1 的内容被换成页面 4 的内容,置换后的情况如下:
虚拟页号 | 页帧(页框、物理块) | 装入时间 | 最近访问时间 | 访问位 | 修改位 |
---|---|---|---|---|---|
2 | 0 | 60 | 161 | 0 | 1 |
4 | 1 | 170 | 170 | 1 | 0 |
0 | 2 | 26 | 162 | 1 | 0 |
3 | 3 | 20 | 163 | 1 | 1 |
例 2(2009 真题)
【例 2】在某个请求分页管理系统中,假设某进程的页表内容如下表所示。
页号 | 页框(Page Frame)号 | 有效位(存在位) |
---|---|---|
0 | 120H | 1 |
1 | --- | 0 |
2 | 850H | 1 |
页面大小为 4KB,一次内存的访问时间是 200ns,一次快表(TLB)的访问时间是 20ns,处理一次缺页的平均时间为 109ns(已含更新 TLB 和页表的时间),进程的驻留集大小固定为二页,采用最近最久未使用置换算法(LRU)和局部置换策略。
假设:(a)TLB 初始为空;(b)地址转换时先访问 TLB,若 TLB 未命中,再访问页表(忽略访问页表之后的 TLB 更新时间);(c)有效位为 0 表示页面不在内存,产生缺页中断,缺页中断处理后,返回到产生缺页中断的指令处重新执行。
现设有虚地址访问序列 2345H、1876H、258FH,请问:
(1)依次访问上述三个虚地址,各需多少时间?给出计算过程。
(2)基于上述访问序列,虚地址 1876H 的物理地址是多少?请说明理由。
【解】(1)页面大小为 4KB,页内偏移量为 12 位,则虚地址的剩余部分为页号。
- 2345H:页号为 2,在 TLB 寻找,没有找到;再去页表寻找,有效位为 1,找到了;此时将页号 2 和对应的页框号 850H 写入 TLB 中,然后访存。因此所花时间为:
查 TLB + 访存 + 访存 = 20ns + 200ns + 200ns = 420ns
。 - 1876H:页号为 1,在 TLB 寻找,没有找到;再去页表寻找,有效位为 0,缺页;发生缺页中断,调入页面,此时将页号 1 和对应的页框号写入 TLB 和页表中;返回被中断的指令,重新查询 TLB,然后访存。因此所花时间为:
查 TLB + 访存 + 缺页中断 + 查 TLB + 访存 = 20ns + 200ns + 109ns + 20ns + 200ns = 109ns
。 - 258FH:页号为 2,在 TLB 寻找,找到了;然后访存。因此所花时间为:
查 TLB + 访存 = 20ns + 200ns = 220ns
。
【注】很多同学在第二次访存时没有多加一次快表的查询时间,这是不对的。请注意,执行完缺页中断后 CPU 将返回到被中断的位置,然后重新执行被中断的指令,这时 CPU 还是跟之前一样去快表查记录,这时肯定能找到对应记录。如上图为整个地址翻译的过程,做错的同学应该是对上面流程不太熟悉。建议每次做这种题时都把上图画出来,这样就不会错了!
(2)进程的驻留集大小固定为二页,采用最近最久未使用置换算法(LRU)和局部置换策略。注意到页表中,刚好有两个有效的页号,对应该进程的驻留集大小。我们也可以得知,系统分配给进程的页框号(或内存块号)是 120H 和 850H,由于采用局部置换策略,这两个页框是不会被系统剥夺的。
页号 | 页框(Page Frame)号 | 有效位(存在位) |
---|---|---|
0 | 120H | 1 |
1 | --- | 0 |
2 | 850H | 1 |
访问虚地址 2345H 时,访问页号 2,由于对应的页号 2 在进程页面中,所以不会发生页置换。
访问虚地址 1876H 时,由于对应的页号 1 不在进程页面中,所以会发生页置换。根据 LRU 算法,刚刚访问过页号 2,因而最近最久未使用的页号为 0,页号 0 会被换为页号 1(此时缺页中断负责将页号为 1 的页面内容调入页框号为 120H 的页框中),对应的页框号为 120H,物理地址为 120876H。此时页表如下:
页号 | 页框(Page Frame)号 | 有效位(存在位) |
---|---|---|
1 | 120H | 1 |
0 | --- | 0 |
2 | 850H | 1 |
例 3(2012 真题)
【例 3】某请求分页系统的页面置换策略如下:从 0 时刻开始扫描,每隔 5 个时间单位扫描一轮驻留集(扫描时间忽略不计)且在本轮没有被访问过的页框将被系统回收,并放入到空闲页框链尾,其中内容暂时不清空。当发生缺页时,如果该页曾被使用过且还在空闲页链表中,则将其重新放回进程的驻留集中;否则,从空闲页框表头部取出一个页框。忽略其他进程的影响和系统开销。初始时进程驻留集为空。目前系统空闲页的页框号依次为 32、15、21、41。进程 P 依次访问的<虚拟页号,访问时刻>为 <1,1>、< 3,2>、<0,4>、<0,6>、<1,11>、<0,13>、<2,14>。请回答下列问题。
(1)访问<0,4>时,对应的页框号是什么?说明理由。
(2)访问<1,11>时,对应的页框号是什么?说明理由。
(3)访问<2,14>时,对应的页框号是什么?说明理由。
(4)该策略是否适合于时间局部性好的程序?说明理由。
【解】
- 第一次扫描到第二次扫描前:
访问页面 | 无 | 1 | 3 | 0 |
---|---|---|---|---|
时刻 | 0 | 1 | 2 | 4 |
页框号 32 | X | 1 | 1 | 1 |
页框号 15 | X | X | 3 | 3 |
页框号 21 | X | X | X | 0 |
页框号 41 | X | X | X | X |
缺页 | √ | √ | √ | |
空闲页框链 | 32->15->21->41 | 15->21->41 | 21->41 | 41 |
- 第二次扫描到第三次扫描前:
访问页面 | 无 | 0 |
---|---|---|
时刻 | 5 | 6 |
页框号 32 | 1 | 1 |
页框号 15 | 3 | 3 |
页框号 21 | 0 | 0 |
页框号 41 | X | X |
缺页 | ||
空闲页框链 | 41 | 41 |
- 第三次扫描到第四次扫描前:
访问页面 | 无 | 1 | 0 | 2 |
---|---|---|---|---|
时刻 | 10 | 11 | 13 | 14 |
页框号 32 | X | 1 | 1 | 1 |
页框号 15 | X | X | X | X |
页框号 21 | 0 | 0 | 0 | 0 |
页框号 41 | X | X | X | 2 |
缺页 | √ | √ | ||
空闲页框链 | 41->32(1)->15(3) | 41->15(3) | 41->15(3) | 15(3) |
【注】空闲页框链中的括号表示该页框中曾经存放的页面号。
理清整个过程后,开始解答:
(1)访问<0,4>时,对应的页框号是 21。
(2)访问<1,11>时,对应的页框号是 32。
(3)访问<2,14>时,对应的页框号是 41。
(4)该策略适合时间局部性好的程序。因为时间局部性越好,在有限的进程驻留集下重复从空闲页框链表中取回页表项到驻留集的几率就越大。
4 程序的编译、链接和装入
4.1 编译
编译:由编译程序将目标源代码编译成若干目标模块。
4.2 链接
链接:由链接程序将编译后形成的一组目标模块及所需的库函数链接在一起,形成完整的装入模块。此阶段将形成程序的逻辑地址。
程序的链接有三种方式:
链接方式 | 描述 |
---|---|
静态链接 | 在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的可执行程序,以后不再拆开 |
装入时动态链接 | 将用户源程序编译后所得到的一组目标模块,在装入内存时,釆用边装入边链接的链接方式 |
运行时动态链接 | 对某些目标模块的链接,是在程序执行中需要该目标模块时,才对它进行的链接。其优点是便于修改和更新,便于实现对目标模块的共享 |
【注】程序的动态链接与程序的逻辑结构有关,而分段存储管理将程序划分为几个逻辑段,因此有利于动态链接。
4.3 装入
装入:装入程序将装入模块装入内存。此阶段将程序的逻辑地址变换为程序的物理地址。
程序的装入有三种方式:
装入方式 | 描述 |
---|---|
绝对装入 | 如果知道程序将驻留在内存的某个位置,编译程序将产生绝对地址的目标代码。绝对装入程序按照装入模块中的地址,将程序和数据装入内存。由于程序中的逻辑地址与实际内存地址完全相同,故不需对程序和数据的地址进行修改 |
可重定位装入(静态重定位) | 程序中的地址都是相对于起始地址的,对程序的指令和地址修改通常是在装入时一次完成的。系统必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。此外,作业一旦进入内存后,在整个运行期间不能在内存中移动,也不能再申请内存空间 |
动态重定位 | 装入程序在把装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行,需要重定位寄存器的支持 |
【注 1】整个系统只有一个重定位寄存器。
【注 2】程序中所使用的绝对地址(物理地址、实地址),可在编译或汇编时给出,也可由程序员直接赋予。而通常情况下在程序中釆用的是符号地址(逻辑地址、虚拟地址),编译或汇编时再转换为绝对地址。(程序中使用符号名来访问存储单元,而符号名存储的是逻辑地址,而逻辑地址能够转化为物理地址)