操作系统-王道老师
第三章-虚拟内存
目录:
1.虚拟内存的基本概念
1.1 传统存储管理方式的特征和缺点
1.2 局部性原理
1.3 虚拟内存的定义和特征
1.4 如何实现虚拟内存技术
2.请求分页管理方式
2.1 页表机制
2.2 缺页中断机构
2.3 请求分页存储管理过程
3.页面置换算法
3.1 最佳置换算法
3.2 先进先出置换算法
3.3 最近最久为使用置换算法
3.4 时钟置换算法
3.5 改进型时钟置换算法
3.6 工作集
4.页面分配策略
4.1 驻留集
4.2 页面分配、置换策略
4.3 调入页面的时机
4.4 从何处调页
4.5 抖动(颠簸)现象
4.6 工作集
1. 虚拟内存的基本概念
1.1 传统存储管理方式的特征和缺点
-
一次性:作业必须一次性全部装入到内存后才能成功运行。 这会造成两个问题:
a. 作业很大的时候,,不能全部装到内存中,导致大作业无法运行;
b. 当大量作业要求运行时,由于内存无法容纳所有的作业,因此只有少量作业能运行,导致多到程序的并发度下降;
-
驻留性:一旦作业被装入了内存,就会一直驻留在内存中,直至作业运行结束。 事实上,在一个时间段内,只需要访问作业的一小部分数据即可以正常运行,这就导致内存中会驻留大量的、暂时用不到的数据,浪费了宝贵的内存资源。
1.2 局部性原理
时间局部性:
如果执行的程序中某条指令,在不久之后可能再次执行,如果某个数据访问过,不久之后该数据可能被再次访问。(因为程序中有大量的循环操作)
空间局部性:
一旦程序访问某个存储单元,在不久之后,其附近的单元页很有可能被访问(因为很多数据在内存中是连续存放的,并且程序的指令也是顺序地在内存中存放的)
高速缓冲技术的思想:
将近期会频繁访问到的数据放到更高速的存储器中,暂时用不到的数据放在更低速的存储器中。
1.3 虚拟内存的定义和特征
定义:
- 基于局部性的原理,在程序装入时,可以将程序中很快会用的部分装入到内存中,暂时用不到的部分留在外存中,就可以让程序开始执行。
- 在程序的执行过程中,当所访问的信息不再内存中时,由操作系统负责将所需的信息从外存中调入,然后执行程序。
- 若内存空间不够,由操作系统将内存中暂时不用的信息调出到外存中。
- 在操作系统的管理下,在用户看来似乎有一个比实际内存大的多的内存,这就是虚拟内存。
易混淆知识点:
虚拟内存最大容量和实际容量的问题
特征:
- 多次性: 无需在作业运行时就一次性全部装入到内存,而是允许被分成多次调入内存 (解决传统一次性问题)
- 对换性: 在作业运行时无需一直常驻内存,而是在运行在运行的过程中,将作业换入换出 (解决传统驻留性问题)
- 虚拟性: 在逻辑上扩充了内存的容量,使用户看到的内存容量远大于实际的容量。
1.4 如何实现虚拟内存技术
虚拟内存技术,允许作业多次调入内存,如果采用连续分配方式,会不方便实现,因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上。
虚拟存储技术的实现:
- 请求分页存储管理
- 请求分段存储管理
- 请求段页式存储管理
实际上就是结合传统存储管理方式,添加利用局部性原理添加虚拟技术,完成虚拟存储技术的实现。
2. 请求分页存储管理
请求分页存储管理与内存分页存储管理的主要区别:
在程序执行过程中,当所访问的信息不在内存中,由操作系统负责将所需信息从外存中调入内存,然后执行程序,
若内存空间不够,有操作系统负责将内存中暂时用不到的信息换出到外存。
2.1 页表机制
页表新增四个字段说明:
- 状态位: 是否已经被调入内存中
- 访问字段: 可记录最近被访问过几次,或记录上次访问的时间,供置换算法选择页面时参考
- 修改位: 页面调入内存后是否被修改过
- 外存地址: 页面在外存中的存放位置
2.2 缺页中断机构
假设此时我要访问逻辑地址 = (页号,页内偏移量)=(0,1024)会进行如下步骤:
- 在请求分页系统中,每当要访问的页面不在内存中,便产生一个缺页中断,然后由操作系统的缺页中断处理程序处理中断。此时缺页的进程阻塞,放入阻塞队列,调页完成后再将其唤醒,放回到就绪队列
- 在调页时,如果有空闲块,则为进程分配一个空闲块,将所缺页面装入该块,并修改页表中的相应的页表项
- 如果内存中没有空闲块,则有页面置换算法选择一个页面淘汰,若该页面在内存期间修改过,则要将其写回外存,未修改的页面无需写回外存。
缺页中断属于内中断:
缺页中断是因为执行的指令要访问的目标页面为调入内存中,因此属于内种一条指令在执行期间,可能产生多次缺页中断。
2.3 请求调用存储管理执行过程
基于快表的流程,第一次访问内存块号信息放入到快表中,方便查询
补充细节:
- 只有“写指令”才需要修改“修改位”。并且,一般来说只需修改快表中的数据,只有要将.快表项删除时才需要写回内存中的慢表。这样可以减少访存次数。
- 和普通的中断处理一样,缺页中断处理依然需要保留CPU现场。
- 换入/换出页面都需要启动慢速的I/O操作,可见,如果换入/换出太频繁,会有很大的开销。
- 页面调入内存后,需要修改慢表,同时也需要将表项复制到快表中。
3. 页面置换算法
3.1 最佳置换算法(OPT)
每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率(但此算法是无法实现的)。
最佳置换算法是不存在的,因为我们必须要提前直到该进程执行过程中需要访问的所有页面的页号,在真实系统中,我们是不可能知道下一个执行的页面是哪一个,所以最佳置换算法是无法实现的。
3.2 先进先出置换算法(FIFO)
每次淘汰的页面是最早进入内存的页面。
把调入内存的页面根据调入的先后顺序排成一个队列,需要换出页面时选择队头页面即可。队列的最大长度取决于系统为进程分配了多少内存块。
3.3 最近最久未使用置换算法(LRU)
每次淘汰的页面是最近最久未使用的页面。
赋予每个页面对应的页表项中,用访问字段记录自上次访问以来所经历的时间t。当需要淘汰一个页面时,选择现有的页面中t最大的,即最近最久未使用的页面。
3.4 时钟置换算法(CLOCK)
为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位置为1。当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出;如果是1,则将它置为0,暂不换出,继续检查下一个页面,若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置为0后,再进行第二轮扫描(第二轮扫描中一定会有访问位为0的页面,因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描)
3.5 改进型时钟置换算法
简单的时钟置换算法仅考虑到一个页面最近是否被访问过。事实上,如果被淘汰的页面没有被修改过,就不需要执行I/O操作写回外存。只有被淘汰的页面被修改过时,才需要写回外存。
因此,除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/O操作。这就是改进型的时钟置换算法的思想。修改位=0,表示页面没有被修改过;修改位=1, 表示页面被修改过。
算法规则:
简单来说,就是选择淘汰时,需要消耗系统资源最少的页面,
第一轮: 先搜索是否有(0,0)空闲并未被修改过,不修改任何标志。
如果没有就降低要求,第二轮: 选择(0,1)空闲但被修改过,没找到的话,就会将所有的访问位设为1。
修改过后在进行,第三轮: 选择(0,0),如果有选择替换
没有找到 第四轮: 选择(0,1),因为之前已经将所有的访问位替换了0,所有一定能找到一个替换目标
所以改进型CLOCK置换算法选择一个淘汰页面最多会进行四轮扫描。
3.6 五种算法对比
4. 页面分配策略
4.1 驻留集
-
驻留集: 指请求分页存储管理中给进程分配的物理块的集合。
在采用了虚拟存储技术的系统中,驻留集大小一般小于进程的总大小。若驻留集太小,会导致缺页频繁,系统要花大量的时间来处理缺页,实际用于进程推进的时间很少;驻留集太大,又会导致多道程序并发度下降,资源利用率降低。所以应该选择-一个合适的驻留集大小。
4.2 页面分配、置换策略
固定分配: 操作系统为每个进程分配一组固定数目的物理块,在进程运行期间不再改变。即驻留集
可变分配: 先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少。
局部置换: 发生缺页时只能选进程自己的物理块进行置换。
全局置换: 可以将操作系统保留的空闲物理块分配给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程。
上面两种分配方式和置换算法可以结合得到以下三种:
固定分配局部置换:
系统为每个进程分配一定数量的物理块,在整个运行期间都不改变。若进程在运行中发生缺页,则只能从该进程在内存中的页面中选出一页换出,然后再调入需要的页面。
**这种策略的缺点是:**很难在刚开始就确定应为每个进程分配多少个物理块才算合理。(采用这种策略的系统可以根据进程大小、优先级、或是根据程序员给出的参数来确定为-一个进程分配的内存块数)
可变分配全局置换:
刚开始会为每个进程分配一定数量的物理块。操作系统会保持一个空闲物理块队列。当某进程发生缺页时,从空闲物理块队列中取出一块分配给该进程;若已无空闲物理块,则可选择一个未锁定的页面换出外存,再将该物理块分配给缺页的进程。采用这种策略时,只要某进程发生缺页,都将获得新的物理块,仅当空闲物理块用完时,系统才选择一个未锁定的页面调出。被选择调出的页可能是系统中任何一一个进程中的页,因此这个被选中的进程拥有的物理块会减少,缺页率会增加。
可变分配局部置换:
刚开始会为每个进程分配一定数量的物理块。当某进程发生缺页时,只允许从该进程自己的物理块中选出一个进行换出外存。如果进程在运行中频繁地缺页,系统会为该进程多分配几个物理块,直至该进程缺页率趋势适当程度;反之,如果进程在运行中缺页率特别低,则可适当减少分配给该进程的物理块。
可变分配全局置换: 只要缺页就给分配新物理块
可变分配局部置换: 要根据发生缺页的频率来动态地增加或减少进程的物理块
4.3 何时调入页面
- 预调页策略:根据局部性原理,一次调入若千个相邻的页面可能比一次调入一个页面更高效。但如果提前调入的页面中大多数都没被访问过,则又是低效的。因此可以预测不久之后可能访问到的页面,将它们预先调入内存,但目前预测成功率只有50%左右。故这种策略主要用于进程的首次调入,由程序员指出应该先调入哪些部分。
- 请求调页策略:进程在运行期间发现缺页时才将所缺页面调入内存。由这种策略调入的页面一-定会被访问到,但由于每次只能调入一页,而每次调页都要磁盘I/O操作,因此I/0开销较大。
4.4 从何处调页
- 系统拥有足够的对换区空间:页面的调入、调出都是在内存与对换区之间进行,这样可以保证页面的调入、调出速度很快。在进程运行前,需将进程相关的数据从文件区复制到对换区。
- 系统缺少足够的对换区空间:凡是不会被修改的数据都直接从文件区调入,由于这些页面不会被修改,因此换出时不必写回磁盘,下次需要时再从文件区调入即可。对于可能被修改的部分,换出时需写回磁盘对换区,下次需要时再从对换区调入。
- UNIX方式:运行之前进程有关的数据全部放在文件区,故未使用过的页面,都可从文件区调入。若被使用过的页面需要换出,则写回对换区,下次需要时从对换区调入。
4.5 抖动(颠簸)现象
刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)
关的数据全部放在文件区**,故未使用过的页面,都可从文件区调入。若被使用过的页面需要换出,则写回对换区,下次需要时从对换区调入。
4.5 抖动(颠簸)现象
刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)