操作系统(thuOS)笔记(六) 第八讲 虚拟存储概念
8.1 虚拟存储的需求背景
在非连续存储内存分配的基础上,可以把一部分内容放到外存里的做法。这样,应用程序有更大的空间可以使用。
之前计算机组成原理学过,SRAM非易失价格便宜,DRAM速度快价格贵,很难折中价格和性能
代码都放到内存里不够了,不够用的原因是多线程、多进程、并发性提高。
解决办法:
把代码分成若干模块,明确它们之间的调用关系。如果没有调用关系,那就需要由用户自己确定什么时候把一个模块加进内存,什么时候把另一个加进内存。这样做的应用开发难度会很高。
交换的单位是一个进程的整个地址空间,这时的开销是很大的。在早期没有非连续存储内存分配时是一个办法。
有了非连续存储内存分配后,可以实现虚拟存储。即,在有限容量的内存中,以页为单位自动装入更多更大的程序。
详细的介绍在后面几节。
8.2 覆盖和交换
覆盖技术
依据程序的逻辑结构,将程序划分成若干功能相对独立的模块。把相互没有调用关系的模块分成一组,它们共享一块内存区域。通过共享让整个进程占用的存储空间变小,从而能在一个小内存的系统上运行。
举例说明:
假如物理内存大小不够190K,A和其他的都有关系,单独分一组;B和C没有关系,分一组;DEF没有关系,分一组。
每一组按最大的来分配内存:
刚开始时,ABD在内存中:
运行一段时间后,B调用D,C调用E
最后F放进来,替换掉E
可以根据分组对空间进行优化
不足:增加编程困难,增加执行时间
交换技术
这里讨论的和覆盖技术不同。现在。一个程序运行的内存一定是够用的,由于多道程序运行,导致内存空间不足,并不考虑所有内存装不下一个程序的情况。
实现的方法是,将暂时不用的程序放到外存
示意图
交换:
面临的问题:
交换时机,何时进行交换?
交换区大小,占用一定的存储空间的
程序换入时的重定位:换出后再换入时,需要放回原处吗?如果不放回原处,函数调用和跳转时该怎么办?
覆盖和交换的比较
覆盖中的逻辑关系,操作系统是很难掌握的,因此需要手动给出。
那么有没有可能,由操作系统来做,又不以整个进程为单位来做?这就是虚拟存储要做的事情。
8.3 局部性原理
想要实现的是这样一个目的
下面来看局部性原理
时间局部性、空间局部性、分支局部性(如for循环,除了最后一次循环,其他时候都是跳转到开头)
不同程序编写方法的局部性特征
每个元素占四个字节,那每一行占一页
8.4 虚拟存储概念
只要有把内存中的页或段往外换,就加上“虚拟”
与交换技术相比,虚拟存储只转移部分页面到外存中
虚拟存储支持的技术
8.5 虚拟页式存储
管理
在页式存储管理的基础上,增加请求调页和页面置换
思路如下
如图所示,如果要访问的页不在内存中,就涉及到虚拟页式存储了。与之前的物理内存管理相比,多了个无效的标志位,来表示缺页。
表示该页面是否在内存中,如果在内存中,那对应的一定能找到物理页帧号
驻留位有效的情况下,修改位表示该页是否被修改过,以此判断回收时是否把它写会外存。如果没有修改过,就不需要再写回到外存
统计这一页是否被经常访问
保护位表示允许访问的方式
举例:16位的逻辑地址,从0到64位物理内存只有32K。页面大小为4K
下图中,逻辑地址空间中能够与物理地址空间一一对应的用数字表示,不能对应的用X表示。
那么X隐含驻留位为0,7表示驻留位为1
此时执行一条指令MOV REG, 8192
,则这个时候是有的
再来一条指令MOV REG, 32780
,这时是缺页
X86页表项结构,这是上一讲的,逻辑地址到物理地址的映射关系。通过Dir找到一级页表中的PPN,通过一级页表PPN找到二级页表的起始地址,再根据Table找到二级页表PPN,加上Offset就是物理地址了。
虚拟存储变化的是页表项里的东西,标志位发生变化,如刚才提到的驻留位、可写标志、用户态标志(表示权限)、透写位(CPU向cache写入数据时,也向后端存储写一份)、关闭高速缓存(如果有IO操作,这里的缓存会影响语意)、修改位、保留位(为后续改动留有空间)。
8.6 缺页异常
缺页异常的处理流程
指令要load M,先去页表中查看驻留位,如果缺页则产生异常,然后在外存中查找页面,将页面换入物理内存,并对页表项标志位进行修改,最后重新执行导致异常的指令。
异常处理过程
另一个问题:虚拟页式存储中的外村管理
第一种是对换区,Linux和Unix都是这么干的
另一种是保存成一个文件
最后一个问题,讨论虚拟页式存储管理的性能
例子:
p需要足够小才能有很好的性能。