3. 内存空间的扩充
Last updated
Last updated
覆盖技术用来解决程序大小超过物理内存总和问题
思想:将程序分为多个段(多个模块),常用的段常驻内存,不常用的段在需要时调入内存
内存中分为一个固定区和若干个覆盖区。把要常驻内存段放在固定区,调入后就不再调出(除非运行结束);不常用的段放在覆盖区,需要用到时调入内存,用不到时调出内存
其中 A 一直运行,A 会调用 B 或 C(不会同时调用),B 会调用 D,C 会调用 E 或 F(不会同时调用)。可知 B、C 不可能同时进入内存,D、E、F 不可能同时进入内存,所以开辟两个覆盖区即可(节约内存)
必须由程序员声明覆盖结构,操作系统完成自动覆盖。缺点:对用户不透明,增加了用户编程负担
思想:内存空间紧张时,系统将内存中某些进程暂时换出外存(挂起),把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)
三个问题:
被换出的进程应该保存在外存(磁盘)的什么位置?
磁盘存储空间分为对换区 & 文件区
文件区:采用离散分配方式,存放文件(主要追求磁盘空间的利用率)
对换区:采用连续分配方式,存放换出进程的数据(主要追求换出换入速度)
对换区的 I/O 速度比文件区更快
什么时候应该换出?
许多内存运行且内存吃紧时进行,而系统负荷降低就停止
应该换出哪些进程?
优先换出阻塞进程
优先换出优先级低的进程
有的系统还会考虑驻留时间
注意:PCB 会常驻内存,不会被换出内存,换出的仅仅是进程的数据部分
一次性:作业必须一次性全部装入内存后才能开始运行
作业很大时,不能全部装入内存,导致大作业无法运行
当大量作业要求运行时,由于内存无法容纳所有的作业,因此只有少量作业能运行,导致多道程序并发度下降
驻留性:一旦作业被装入内存,就会一直驻留内存中,直至作业运行结束
事实上,在一个时间段内,只需要访问作业的一小部分数据即可正常运行
基于局部性原理,在程序装入时,可以将程序中很快用到的部分装入内存,暂时用不到的部分留在外存,就可以让程序开始执行
在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需要的信息从外存调入内存,然后继续执行程序
若内存空间不够时,由操作系统负责将内存中暂时用不到的信息换出到外存
在操作系统的管理下,在用户看来似乎有一个比实际内存大得多的内存,这就是虚拟内存
特点:
多次性:无需在作业运行时一次性全部装入内存,而是运行被分为多次调入内存
兑换性:在作业运行时无需一直常驻内存,而是允许在作业运行过程中,将作业换入、换出
虚拟性:从逻辑上扩充了内存的容量,使用户看到的内存容量,远大于实际容量
在传统的非连续分配存储管理的方式下进行改进:请求分页存储管理、请求分段存储管理、请求段页式存储管理
主要区别:
在程序执行过程中,当所访问的信息不再内存时,由操作系统负责将所需要信息从外存调入内存,然后继续执行程序
若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存
新增两个功能
请求调页:操作系统需要知道每个页面是否已经调入内存;如果还没调入,那么也需要知道该页面在外存中存放的位置
页面置换:操作系统需要通过某些指标来决定到底换出哪个页面(需要记录页面是否被修改)
添加了四个标志位:状态位、访问字段、修改位、外存地址
在请求分页系统中,每当要访问的页面不在内存时,便产生一个缺页中断,然后由操作系统的缺页中断处理程序处理中断
此时缺页的进程阻塞,放入阻塞队列,调页完成后再将其唤醒,放回就绪队列
如果内存中有空闲块,则为进程分配一个空闲块,将所缺页面装入该块,并修改页表中相应的页表项
如果内存中没有空闲块,则由页面置换算法选择一个页面淘汰,若该页面在内存期间被修改过,则要将其写回外存。未修改过的页面不用写回外存
只有“写指令”才需要修改 “修改位”。并且,一般来说只需修改快表中的数据,只有要将快表项删除时才需要写回内存中的慢表。这样可以减少访存次数
和普通的中断处理一样,缺页中断处理依然需要保留CPU现场
需要用某种“页面置换算法” 来决定一个换出页面
换入/换出页面都需要启动慢速的I/O操作,可见,如果换入/换出太频繁,会有很大的开销
页面调入内存后,需要修改慢表,同时也需要将表项复制到快表中
每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被使用访问的页面
最佳置换算法可以保证最低的缺页率,但实际上,只有在进程执行的过程中才能知道接下来会访问到 的是哪个页面。操作系统无法提前预判页面访问序列。因此,最佳置换算法是无法实现的
每次选择淘汰的页面是最早进入内存的页面
实现方法:把调入内存的页面根据调入的先后顺序排成-一个队列,需要换出页面时选择队头页面即可。 队列的最大长度取决于系统为进程分配了多少个内存块
Belady异常:当为进程分配的内存块增大时,出现缺页次数不减反增的异常现象
只有FIFO算法会产生Belady异常。另外,FIFO算法虽然实现简单,但是该算法与进程实际运行时的 规律不适应,因为先进入的页面也有可能最经常被访问。因此,算法性能差
每次淘汰的页面是最近最久未使用的页面
实现方法:赋予每个页面对应的页表项中,用访问字段记录该页面上次被访问以来所经历的时间 t。当需要淘汰一个页面时,选择现有页面中 t 值最大的,即最近最久未使用的页面
该算法的实现需要专门的硬件支持,虽然算法性能好,但是现实困难,开销大
改进上述三种算法,最佳置换算法性能最好,但无法实现;先进先出置换算法实现简单,但算法性能差;最近最久未使用置换算法性能好,是最接近最佳置换算法性能的,但是实现需要专门的硬件支持,算法开销大
时钟置换算法是一种性能和开销较均衡的算法,又称 CLOCK 算法,或最近未使用算法(LRN,Not Recently Used)
实现方法:为每个页面设置一个访问位,将内存中页面都通过指针链接形成一个循环队列
当某页面被访问时,将其访问位置为 1
当需要淘汰一个页面时,只需检查页面的访问位
如果访问位是 0,则选择换出
如果访问位是 1,则将它置为 0,暂不换出,继续检查下一个页面
如果第一轮扫描没有符合条件的页面,则继续扫描第二轮(第二轮一定有访问位为 0 的页面)
所以该算法最多扫描两轮
简单的时钟置换算法仅仅考虑了是否被访问过,如果一个页面访问过但是未被修改,淘汰时就不需要写回内存,应该优先淘汰此类的页面,可以减少 I/O 操作写回内存
用两个标志位(访问位,修改位)来记录一个页面是否被访问过,是否被修改过。在其它条件都相同的时候,应该优先淘汰没有修改过的页面,避免 I/O 操作
算法规则:将所有可能被置换的页面排成一个循环队列
第一轮:从当前位置开始扫描到第一个(0,0)的页面用于替换。本轮扫描不修改任何标志位(第一优先级:最近没访问,且没修改的页面)
第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0,1)的页面用于替换。本轮所有扫描过的页面访问位设置为 0(第二优先级:最近没访问,但修改过的页面)
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0,0)的页面用于替换。本轮扫描比修改任何标志位(第三优先级:最近访问过,但没修改的页面)
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0,1)的页面用于替换(第四优先级:最近访问过,且修改过的页面)
驻留集:请求分页存储管理中给进程分配的物理块的集合
采用虚拟存储技术系统中,驻留集大小一般小于进程总大小
若驻留级太小,会导致频繁缺页,系统需要花费大量时间来处理缺页
若驻留级太大,会导致多道程序并发度下降,资源利用率降低
固定分配:操作系统为每个进程分配一组固定数目的物理块,在进程运行过程中驻留集大小不变
可变分配:操作系统先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少,驻留集大小可变
局部置换:发生缺页时只能选进程自己的物理块进行置换
全局置换:可以将操作系统保留的空闲物理块分配给进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程
固定分配局部置换:系统为每个进程分配一定数量的物理块,在整个运行期间都不改变。若进程在运行中发生缺页,则只能从该进程在内存中的页面中选出一页换出,然后再调入需要的页面。这种策略的缺点是:很难在刚开始就确定应为每个进程分配多少个物理块才算合理。(采用这种策略的系统可以根据进程大小、优先级、或是根据程序员给出的参数来确定为一个进程分配的内存块数)
可变分配全局置换:刚开始会为每个进程分配一定数量的物理块。操作系统会保持一个空闲物理块队列。当某进程发生缺页时,从空闲物理块中取出一块分配给该进程;若已无空闲物理块,则可选择一个未锁定的页面换出外存,再将该物理块分配给缺页的进程。采用这种策略时,只要某进程发生缺页,都将获得新的物理块,仅当空闲物理块用完时,系统才选择一个未锁定的页面调出。被选择调出的页可能是系统中任何一个进程中的页,因此这个被选中的进程拥有的物理块会减少,缺页率会增加
可变分配容局置换:刚开始会为每个进程分配一定数量的物理块。当某进程发生缺页时,只允许从该进程的自己的物理块中选出一个进行换出外存。如果进程在运行中频繁地缺页,系统会为该进程多分配几个物理块,直至该进程缺页率趋势适当程度;反之,如果进程在运行中缺页率特别低,则可适当减少分配给该进程的物理块。
可变分配全局置换:只要缺页就给分配新物理块
可变分配局部置换:要根据发生缺页的频率来动态地增加或减少进程的物理块
置换算法
算法规则
优缺点
OPT
优先淘汰最长时间内不会被访问的页面
缺页率最小,性能最好;
但无法实现
FIFO
优先淘汰最先进入内存的页面
实现简单,但性能差;
可能出现 Belady 异常
LRU
优先淘汰最近最久未访问的页面
性能很好;
但需要硬件支持,算法开销大
CLOCK(NRU)
优先淘汰最近未访问的页面
实现简单,算法开销小;
但未考虑页面是否被修改过
改进型 CLOCK(改进型 NRN)
优先淘汰最近未访问且未修改的页面
算法开销较小,性能也不错