操作系统——虚拟内存管理
传统存储管理方式
- 传统管理方式特征
传统存储管理方式具有一次性
和驻留性
的特点,一次性
指的是作业必须一次性装入内存后才可以开始运行
,驻留性
指的是作业被装入内存后,就一直驻留在内存中,其任何一部分都不会被换出,直至作业运行结束
- 问题
- 程序通常具有异常错误条件的代码,而这些错误很少发生,所以这些代码几乎从不执行
- 数组、链表等所分配的内存量通常多于实际需要值
- 程序的某些选项和功能很少使用
- 当作业很大而不能全部被装入内存时,该作业无法运行
- 大量作业要求运行时,由于内存不足以容纳所有作业,只能使少数作业先运行,导致多道程序度下降
局部性原理
局部性原理从广义角度上讲属于高速缓存技术,而高速缓存技术依赖于局部性原理,局部性原理主要表现在时间局部性和空间局部性
- 时间局部性
程序中某条执行一旦执行,不久后可能再次执行,某数据一般被访问,不久后可能还会被访问
,产生局部性的典型原因是程序中存在大量的循环
- 空间局部性
一旦程序访问了某个存储单元,不久后其附近的存储单元也将被访问
,主要原因是指令通常是顺序存放和顺序执行
的,数据也一般是以向量、数组、表等形式簇聚形式存储的。
虚拟内存技术
- 虚拟内存
虚拟内存技术允许执行进程不必完全处于内存中,虚拟内存将内存抽象成一个巨大的、统一的存储数组,实现了逻辑内存和物理内存的分离,让用户看到的比实际内存大得多的内存空间
- 优点
- 程序不再受物理可用量限制
- 可以同时运行更多的程序
- 加载或交换每个用户程序到内存所需的I/O会更少
- 特征
- 多次性
无需再作业运行时一次性全部转入内存,允许被分成多次调入内存运行 - 对换性
无需在作业运行时一直常驻内存,允许在作业的运行过程中,进行换入和换出 - 虚拟性
逻辑上扩充内存容量,使用户看到的内存容量远大于实际内存容量
虚拟内存技术实现
- 基础
虚拟内存技术的实现建立在离散分配
的内存管理方式的基础上 - 方式
- 请求分页存储管理
- 请求分段存储管理
- 请求段页存储管理
- 硬件支持
- 一定容量的内外存
- 页表或段表机制,作为主要数据结构
- 中断机构,当用户程序要访问的部分尚未调入内存时,产生中断
- 地址变换机构,实现逻辑地址到物理地址的转换
请求调页
请求调页只要将当前需要的一部分页面装入内存,即可启动作业运行
页表机制
请求分页在一个作业运行之前不要求全部一次性调入内存,故在作业运行过程中,必然会出现要访问的页面不再主存中的情况,故除了页号和对应物理页号,还需在请求页表项中添加4个字段
- 状态位,用于指示该页是否已经调入内存,供出现访问时参考
- 访问字段,记录本页在一段时间内被访问的次数,供置换算法换出页面时参考
- 修改位,标识改页是否被修改过
- 外存地址,指向该页在外存的地址,通常是物理块号,供调入该页时参考
缺页中断机构
若进程所要访问的页面不再主存中,则会产生缺页中断,进行缺页处理。缺页中断作为中断同样要经历保护现场、分析中断原因、进入缺页中断处理程序、中断返回、恢复现场等步骤,但与一般中断不同的是,缺页中断在指令执行期间而非指令执行完后产生和处理中断信号,属于内部中断,一条指令在执行期间可能出现多次缺页中断
地址变换机构
进行地址变换时,先访问块表
- 若找到要访问的页的页表项,则修改页表项中的访问位,然后利用页表项中的物理块号和页内偏移地址形成物理地址
- 若未找到要访问的页的页表项,则到主存中查找页表,查看页表项中的状态位,若对应页面已经调入主存,则进行访问,否则产生缺页中断,进行缺页处理
页面置换算法
最佳置换算法
- 最佳置换算法
最佳(Optimal, OPT)置换算法选择的淘汰页面是以后永不使用的页面,或是在最长时间内不被访问的页面,以获得最低缺页率,置换最长时间不会使用的页面
- 特点
- OPT算法通常可以用来评价其他算法
- 人们无法预知进程在内存下的若干页面中哪个是未来最长时间不再被访问的,因而该算法无法实现
- 在所有算法中具有最低的缺页率
先进先出页面置换算法
- 先进先出页面置换算法
先进先出(First In First Out,FIFO)页面置换算法,调出内存中驻留最久的页面,调入内存的页面根据先后次序链接成队列,设置一个指针总是指向最早的页面
- 特点
- FIFIO页面置换算法不适应进程实际运行规律,最早的页面不一定最不经常被访问
- 可能产生
Belady异常(Belady's anomaly)
,即分配的物理块数增大而页故障树不减反增的异常现象
最近最久未使用算法
- 最近最久未使用算法
最近最久未使用(Least Recently Used, LRU)算法,认为过去一段时间未访问过的页面,在最近将来可能也不会被访问,为每个页面设置一个访问字段记录页面自上次被访问以来所经历的时间,淘汰页面时选择先用页面中访问字段值最大的予以淘汰,也可以采用页码堆栈,每当页面被引用时,它就从堆栈终移除并放到顶部,最近使用的页面总是在顶部,最近最少使用的页面总是在底部
- 特点
- 需要寄存器和栈的硬件支持
- 堆栈类算法不可能出现Belady异常
- 很少有计算机系统能提供足够的硬件类支持真正的LRU页面置换算法
时钟置换算法
CLOCK算法
- 时钟置换算法
时钟置换(CLOCK)算法,又称为最近未用(Not Recently Used, NRU)算法要循环扫描缓冲区,像时钟一样转动,成为CLOCK算法,CLOCK算法给每帧关联一个附加位,称为使用位,某页首次转入主存时,将对应帧的使用位置为1,被访问到时,使用位也只为1,需要进行页替换时,利用一个指针缓冲区完整地循环一周,每遇到一个使用位为1的帧置零,将遇到的第一个帧为0替换,若所有帧都为1,则循环完一周后,所有帧被置为0,选取最初的一个帧,每次指针都指向被替换帧的下一个位置
改进型CLOCK算法
- 改进型CLOCK算法
通过增加使用的位数目,得到更高效地改进型CLOCK算法
- 情况
- 最近未被访问且未被修改(00)
- 最近未被访问且被修改(01)
- 最近被访问且未被修改(10)
- 最近被访问且被修改(11)
- 算法操作步骤
从指针当前位置开始,扫描帧缓冲区,不对使用位进行任何修改,替换遇到的第一个未被访问也未被修改(00)的帧,若未遇到,则重新扫描,找到遇到的第一个最近未被访问且被修改(01)替换,扫描过程中将扫描过的帧使用位置置0,若未找到则再次循环查找,即可找到符合需求的帧
页面分配策略
驻留集大小
驻留集
- 驻留集
驻留集指的是操作系统给一个进程分配的物理页框的结合
- 特点
- 分配给一个进程的存储量越小,任何时候驻留在主存中的进程数越多,从而可以提供处理机的时间利用效率
- 若进程所在主存中的页数过少,尽管存在局部性原理,缺页率依然会相对较高
- 若进程所在主存中的页数过多,由于局部性原理,给特定的进程分配更多的主存空间对该进程的缺页率没有明显影响
策略
- 固定分配局部置换
为每个进程分配一定数目的物理块,整个运行期间都不改变
,运行中出现缺页则只能从分配的内存页面中选取一块换出,然后调入需要的页面,但难以确定每个进程合适的页数,太少会频繁出现缺页中断,太多会使得CPU和其他资源利用率下降
- 可变分配全局置换
为每个进程分配一定数目的物理块,操作系统自身维护一个空闲的物理块队列,当某进程发生缺页时,从空闲物理块队列中分配一个物理块给该进程,将欲调入页装入其中,这样比固定分配局部置换更加灵活,可以动态增加进程物理块
,但可能会盲目地给进程增加物理块,从而使系统多道程序并发能力下降
- 可变分配局部置换
为每个进程分配一定数目的物理块,若某进程出现缺页现象,只允许从该进程所分配的内存页面中调页替换。若该进程在运行中频繁调页,则操作系统会为该进程分配若干物理块,直至该进程的缺页率区域适当程度
,反之,若进程运行中的缺页率特别低,操作系统将适当减少分配给该进程的物理块
,这样的方式保证了进程适当缺页率的同时,保持了系统的多道程序并发能力,但实现相对复杂
调页策略
- 预调页策略
根据局部性原理,可以一次调入若干页以降低缺页率,但若调入的页面大多数不被访问则会导致更高的缺页率,故需要基于预测为基础的预调页策略,将预计不久之后会被访问的页面调入主存 - 请求调页策略
进程运行过程中遇到缺页则提出请求,操作系统将所需页面调入内存,即仅在需要时才加载页面
,但每次只调入一页,可能会导致较高的缺页率,产生过的I/O开销
一般情况下,两种策略同时使用
调入页面选区策略
请求分页系统的外存分两部分:用于存放文件的文件区和用于存放对换页面的对换区,对换区通常采用连续分配方式,而文件区采用离散分配方式,故对换区的磁盘I/O速度比文件区更快
- 情况
- 系统拥有足够的对换区
进程全部从对换区调入页面,提高调页速度,为此,在进程运行前,需将与该进程有关文件复制到对换区 - 系统缺少足够的对换区空间
不会被修改的文件从文件区调入,由于没有修改,换出时不需要调出到文件区,而那些可能被修改的部分,换出时需要调到文件区,需要时再从对换区调入
,由于读的速度比写的更快,所以这样可以减少一些I/O开销 - UNIX方式
与进程有关的文件都放在文件区,即未运行过的页面都从文件区调入
,运行的页面换出到对换区,以后调入这一部分也从对换区,进程请求的共享页面若已经被其他进程调入主存,则无需调入
抖动
- 抖动
抖动(thrashing)指的是各个换出的页面马上又要换入内存,刚刚换入的页面马上又要换出内存这种高度频繁的页面调度的行为,这种现象换页用的时间多于执行的时间
- 成因
操作系统监视CPU利用率,若利用率过低则操作系统引入新的进程来增加多道程度,采用全局置换算法来置换任何页面,而不管这些页面属于哪个进程。若一个进程在一个阶段需要更多的帧
,它开始出现缺页错误,就会从将其他进程的帧换出,而其他进程若也需要这些页面,则会产生缺页错误,再从其他进程获取帧,这样的话操作系统会进行大量的页面调度行为,而调页需要等待调页设备对页面进行换入换出,而很多进程在等待调页设备,CPU利用率会降低。
而CPU利用率一旦降低,CPU调度程序就会引入更多的进程以增加多道程序并行程度,新进程试图从其他运行进程中获取帧,从而导致更多的缺页错误
,这样的情况循环,进程都不能完成,而总是忙于调页 - 解决方案
- 局部置换算法
采用局部置换算法,即进程不能从其他进程获取帧,限制系统抖动现象的产生 - 优先权置换算法那
若进程抖动,你们在大多数时间内会等待调页设备,由于调页设备的平均队列更长,缺页错误的平均等待时间增加
工作集
- 工作集
工作集指的是某段时间内,进程要访问页面集合,工作集模型是基于局部性的假设,用最近访问过的页面来确定工作机
- 实现
定义 Δ \Delta Δ为窗口工作集大小,算法检测最近 Δ \Delta Δ个界面的引用,若一个页面处于活动状态则它处在工作集中,若它不使用,那么它在最后一次引用的 Δ \Delta Δ时间单位后,会被从工作集中删除。操作系统监视每个进程的工作集,并为它分配大于其工作集的帧数(即驻留集帧数大于工作集帧数) - 特点
- 工作集策略可以防止抖动,同时保持尽可能高的多道程序并发程度
- 难以跟踪工作集
鸣谢
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!