引入虚拟内存的逻辑考量
进程中的所有内存访问都是逻辑地址,这些逻辑地址在运行时动态地转换成物理地址。这意味着一个进程可以被换入或换出内存,使得进程可以在执行过程中的不同时刻占据内存中的不同区域
一个进程可以划分成许多块,在执行过程中,这些块不需要连续地位于内存中的不同区域
进程在执行过程中,如果内存中保存着要取的下一条指令的所在块,以及将要访问的下一个数据单元的所在块,那么执行将继续下去。基于此,引入常驻集的概念(进程执行中任何时候都在内存的部分)。当进程执行时,只要所有的内存访问都是在常驻集中,执行就可以顺利进行。基于此
,这里的“块”就是上篇讲到的页或者段。使用段表或者页表纪录进程所有的块。
- 如果处理器需要访问一个不在内存中的逻辑地址(处理访问的块不在内存中),则产生一个中断,操作系统把被中断的进程置于阻塞态,
- 同时把该逻辑地址的进程块读入内存(常驻集)中。这个过程就是虚拟内存换入常驻集的过程。
- 在这个磁盘I/O中断期间,操作系统可以调度另一个进程运行。具体如何调度在下篇中讲到。
- 一旦需要的块成功读入内存,则产生一个I/O中断,控制权从另一个进程交回来,原来处于阻塞态的进程置为就绪态。
虚存支持更有效的多道程序设计,并解除了用户和内存之间的紧密联系。
虚拟内存可行的依据
局部性原理描述了一个进程中程序和数据引用的集簇倾向。局部性原理说明了虚拟内存方案是可行的。
虚拟内存分页
页表结构
P位
表示它所对应的页当前是否在内存中
M位
表示相应页的内容从上一次装入内存中到现在是否已经改变
使用页表把虚拟地址(逻辑地址)转换到物理地址。虚拟地址的页号用于检索页表/查找相应的页框号,并与虚拟地址的偏移量组合起来产生需要的实地址。
大多数虚拟内存方案都在虚存而非实存中保存页表,因此页表和其他页一样都服从分页管理。一个进程正在运行时,它的页表一部分必须在内存中,这一部分包括正在运行的页的页表项,另一部分在虚拟内存中。典型情况下,一个页表的最大长度被限制位一页。
对于大型页表,有多种方案。
两级方案组织大型页表
在这类方案中有一个页目录,每一项指向一个页表,因此如果页目录长度X,并且如果一个页表最大长度是Y,那么这个进程可以有X*Y页。
缺陷是:页表大小与虚拟地址空间的大小成正比。
倒排页表
虚拟地址的页号部分使用一个简单的散列函数映射到散列表中。散列表包含一个指向倒排表的指针,而倒排表中含有页表项。由于多个需您地址可能映射到同一个散列表项中(同义词),因此需要使用一种链接技术管理这种溢出。
#倒排页表里的页结构
- 页号
- 进程标识符
- 控制位
- 链指针
转换检测缓冲区
虚拟内存方案为页表项使用一个特殊的高速缓存,称为转换检测缓冲区(TLB),包含最近用过的页表项。
一次缓冲的工作过程
- 给定一个虚拟地址,处理器检查TLB
- 如果需要的页表项在其中(TLB命中),则检索页框号并形成实地址
- 如果TLB未命中,处理器用也好检索进程页表,并检查页框号并形成实地址,同时更新TLB,使其包含着歌新的页表项。
缺页中断
如果页表项中的P位没有置位,则表示需要的页不在内存中,这时将产生一次内存访问故障。
页尺寸大小的考量因素
内部碎片。
- 页越小,内部碎片总量越少。为优化内存的使用,希望减少内部碎片;
- 页越小,每个进程所需要的页的数目就越多(假设该进程所需要的内存是某个固定值),这就意味着更大的页表;
- 大多数外部存储设备的物理特性,希望页尺寸比较大,实现更有效的数据块传送。
缺页率
- 页尺寸大小与缺页率成开口向下抛物线关系
- 固定页尺寸大小,当内存中的页数目增加时,缺页率下降。
物理内存的大小和程序大小有关
段页式
在段页式的系统中,用户的地址空间可以被程序员划分成许多段,每个段依次划分成许多固定大小的页,页的长度等于内存中的页框大小。如果某一段的长度小于一页,则该段只占据一页。逻辑地址仍然由段号和偏移量组成。段偏移量可视为指定段中的一个页号和偏移量。
分段有助于保护与共享机制。
存储管理采用的算法
内存管理设计的三个基本方面
- 是否使用虚存技术
- 是使用分页,分段还是段页式
- 存储管理的各种算法
读取策略
读取策略确定一个页何时取入内存。
- 请求分页
- 预先分页
放置策略
放置策略决定一个进程块主流在实存中的什么地方。
- 最佳适配
- 首次适配
- 下次适配
置换策略
当内存中的所有页框都被占据,并且需要读取一个新页以处理一次缺页中断时,置换策略决定当前内存中的哪个页将被置换。所有策略的目标都是移出最近最不可能访问的页。
由于局部性原理,在稳定阶段,最近访问的历史和最近将要访问的有很大相关性。
页框锁定
置换策略的一个约束:内存中的某些页框可能是被锁定的。大部分操作系统内核和重要的控制结构就保存在锁定的页框中。
锁定是通过给每个页框关联一个lock位实现,这一位包含在页框表和当前页表中
基本算法
最佳(Optimal,OPT)
置换下次访问距离当前时间最长的那些页,该策略是理想状态的策略。
最近最少使用(Least Recently Used ,LRU)
置换内存中上次使用距离当前最远的页。LRU策略性能接近与OPT策略
实体实现方法
给每一页添加一个最后一次访问的时间戳,每次访问内存时,都更新这个内存对应页的时间戳。
先进先出(FIFO)
把分配给进程的页框视为一个循环缓冲区,按循环方式移动页,它所需要的只是一个指针,这个指针在该进程的页框中循环。
这种方法所隐含的逻辑是置换驻留在内存中最长的页。
时钟(Clock)
时钟算法的性能非常接近LRU,可以通过增加使用的位数,使时钟算法更有效。
页缓冲
被置换出的页不是被丢弃,而是被分配到两个表中的一个。如果该页未被修改,则分配到空闲页链表,如果该页被修改了,则分配到修改页链表中。而页框由列表头部来提供,被置换的页仍然保留在内存中。修改页链表里的页以簇的方式写会外存,大大减少了I/O操作的数目。
驻留集管理
驻留集大小考量
- 分配给一个进程的内存越少,在任何时候驻留在内存中的进程数就越多,增加了操作系统找到一个就绪进程的可能性
- 如果一个进程在内存中的页数比较少,缺页率相对较高(页数足够少,局部性原理失效)
- 给特定进程分配的内存空间过多,局部性原理失效,进程缺页率没有明显提升
管理策略
固定分配策略
一个进程在内存中分配固定数目的页框用语执行时使用
可变分配策略
允许分配给一个进程的页框在该进程的生命周期中不断地发生变化
置换范围
局部置换策略
仅仅在产生这次缺页的进程的驻留页中选择
全局置换策略
内存中所有未被锁定的页都作为置换的候选页,而不管它们属于哪一个进程。
可变分配、局部范围策略的关键要素是,用于确定驻留集大小的原则和变化的时间安排
工作集策略
工作集
指一个进程最近被使用过的页的集合
驻留集
指一个进程在当前内存中的页的集合
并不必集中在紧缺的页访问上,而是集中在进程的缺页率上。缺页中断频率(Page Fault Frequency,PFF)算法
解决局部性过渡问题且开销低于PFF的一种方法是可变采样间隔的工作集策略(Variable-interval Sampled Working Set,VSWS)。该策略由三个参数驱动:采样区间的最大宽度M,采样区间的最小宽度L,采样实例间允许发生缺页中断数目。
清除策略
用于确定在何时将一个被修改过的页写回辅存。请求式清除和预约式清除
加载控制
系统并发度
驻留在内存中的进程数目
L=S准则,通过调整系统并发度,使得缺页中断之间的平均时间等于处理一次缺页中断所需要的平均时间