如何超越物理内存的限制
当作业需要的物理内存大小超过了现有物理内存的大小的时候,主要有覆盖、交换两种方式来解决这一问题。
覆盖(时间上的扩展)
覆盖就是把程序划分为若干个功能上相对独立的程序段,按照其自身的逻辑进行分组,将不可能同时被使用的程序段分到同一组,称为覆盖组(即内存中有你没我,你要上来就把我覆盖掉即可)。
缺点:编程时必须划分程序模块和确定程序之间的覆盖关系,增加了编程复杂度。而且从外存中重新装入覆盖文件的做法,就是在以时间换空间。
交换(空间上的扩展)
交换,就是把暂时不用的某个(或某些)程序及其数据的部分或全部从主存移到辅存中去,以便腾出必要的存储空间;接着把指定程序或数据从辅存读到相应的主存中,并将控制转给它,让其在系统上运行。
-
优点:增加并发运行的程序数目,并且给用户提供适当的响应时间;编写程序时不影响程序结构
-
缺点:对换入和换出的控制增加处理机开销;程序整个地址空间都进行传送,没有考虑执行过程中地址访问的统计特性。
虚拟存储技术
虚拟存储技术的提出,是基于人们想要更好的解决作业所需内存大于实际内存问题的愿望而诞生的。
虚拟存储技术继承了覆盖、交换的核心思想:
- 像覆盖技术那样,不是把程序的所有内容都放在内存中,因而能够运行比当前的空闲内存空间还要大的程序。但做得更好,由操作系统自动来完成,无须程序员的干涉。
- 像交换技术那样,能够实现进程在内存与外存之间的交换,因而获得更多的空闲内存空间。但做得更好,只对进程的部分内容(更小的粒度,如分页)在内存和外存之间进行交换。
其基本理念是:
- 按需装载:在程序装入时,不必将其全部读入到内存,而只需将当前需要执行的部分页或段读入到内存,就可让程序开始执行。
- 缺页调入:在程序执行过程中,如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页或段调入到内存,然后继续执行程序。
- 不用调出(页面置换策略):另一方面,操作系统将内存中暂时不使用的页或段调出保存在外存上,从而腾出空间存放将要装入的程序以及将要调入的页或段――具有请求调入和置换功能,只需程序的一部分在内存就可执行,对于动态链接库也可以请求调入。
虚拟存储技术具体有以下三个特点:
-
给所有进程提供一致的地址空间,每个进程都认为自己是在独占使用单机系统的存储资源。
-
保护每个进程的地址空间不被其他进程破坏,隔离了进程的地址访问。
-
根据缓存原理,上层存储是下层存储的缓存,虚拟内存把主存作为磁盘的高速缓存,在主存和磁盘之间根据需要来回传送数据,高效地使用了主存。
虚拟性以多次性和对换性为基础,多次性和对换性以离散性为基础。
虚拟存储管理与分页、分段区分
其实,分区、分页、分段都是从实存管理角度来谈的,所以那里提的应该实逻辑地址与物理地址之间的转换而不是虚拟地址。不过由于现行很多都是虚拟存储技术,而虚拟存储的内存管理是基于分页、分段、段页式的,引入了请求分页(段)的概念。所以经常谈页式管理这些的时候,会说成虚拟地址和物理地址的转换,这里值得注意一下。
请求分页(段)系统
请求分页,则是为了实现之前基本理念中提到的按需装载、缺页调入、不用调出所提出的,即在必要的时候可以请求将程序所需要的页调入主存之中。在这个系统中,较为重要的问题是替换的时候,应该换出哪些页。
页面置换策略
- OPT 最佳置换策略:从主存中移出永远不再需要的页面,如无这样的页面存在,则应选择最长时间不需要访问的页面。
- FIFO 先进先出策略:总选择作业中在主存驻留时间最长的一页淘汰。这种策略性能较差,而且会出现 belady 现象(即缺页率会随着页框数增加而下降)。
- CLOCK 算法(改进过的 FIFO,也称 NRU 最近未使用)。其核心思想是,我给最近被访问过的页面一次“免死“的机会,当我要换出一个页的时候,我先看你有没有免死金牌,有那我就先不把你换出去找下一个页,没有就把你换出。实际中,会把页面排成一个环形队列,通过一个指针指向当前要被”拷问“的那个页面,当发生缺页中断的时候,问那个页面有没有免死金牌,没有就被换出去,指针指向下一个页面;有就拿走它的免死金牌(只能免死一次),再去问下一个页面直到找到一个没有免死金牌的。
- LRU 最近最少使用:算法核心思想是如果数据最近被访问,那么将来被访问的概率也很高。这是最符合局部性原理的,性能接近最优算法,但由于需要记录页面使用时间的先后关系,硬件开销较大。
工作集与驻留集管理
前面讨论的页面置换策略都是对于一个进程而言的,而工作集、驻留集则是在多进程角度下的概念。
- 进程的工作集:当前正在使用的页面的集合(一般是当前时刻往前划的一段时间内,这段时间被称为窗口尺寸)。
- 进程的驻留集:每个进程驻留在内存的页面集合,或进程分到的物理页框集合。
而引入工作集的目的是依据进程在过去的一段时间内访问的页面来调整常驻集大小,即实现不用调出。并可以通过在进程被换出的时候保留进程当前的工作集(预调页),来让下一次进程被换上的时候尽量少报缺页中断。
而驻留集的管理主要解决的是系统应该为每个活跃进程分配多少个页框的问题。因为分配的页框数越少,同时能驻留在内存中活跃进程数就越多,但是缺页中断的概率也会越来越大,但同时即使给一个进程分配很多页框,其缺页率也不能显著降低。
分配和置换策略(前两个的结合)
分配策略有固定分配和可变分配策略。这里的固定和可变是指给一个进程分配页框数是预先固定的,还是可以动态增加、减少的。可变分配,到底是要增加还是减少就可以根据工作集与驻留集的比较来决定。
置换策略分为局部置换、全局置换。局部置换:就是一个进程的页面替换的时候,能换出的页面只能是自己进程的;全局置换:就是将所有进程的页面放到一起来判断要替换出哪一个。
注意,分配策略与置换策略之间的组合只有固定分配+全局置换是不行的,因为固定分配都固定好了一个进程的页框数,你全局置换却可能修改一个进程的页框数。一般来说,都是采用的可变分配策略+局部置换策略,因为固定太不灵活、全局置换又会导致一个进程自己的驻留集会受到其他进程影响。