第四章讲述的各种存储器管理方式统称为传统存储器管理方式。
传统存储器管理方式特征:
上述的一次性及驻留性特征使得许多在程序运行中不用或暂时不用的程序(数据)占据了大量的内存空间,而一些需要运行的作业又无法装入运行,显然,这是在浪费宝贵的内存资源。
局部性原理
1968年,P.Denning 指出: 程序在执行时将呈现出局部性规律,即在一较短的时间内,程序的执行仅局限于某个部分,相应地,它所访问的存储空间也局限于某个区域。
局限性又表现在下述两个方面:
虚拟存储器定义:
指具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统。其逻辑容量由内存容量和外存容量之和所决定,其运行速度接近于内存速度,而每位的成本却又接近于外存。
可见,虚拟存储技术是一种性能非常优越的存储器管理技术,故被广泛地应用于大、中、小型机器和微型机中。
虚拟存储器特征:
(1)多次性。
指一个作业中的程序和数据无需在作业运行时一次性地全部装入内存,而是允许被分成多次调入内存运行,即只需将当前要运行的那部分程序和数据装入内存即可开始运行。以后每当要运行到尚未调入的那部分程序时,再将它调入。
(2)对换性。
指一个作业中的程序和数据,无须在作业运行时一直常驻内存,而是允许在作业的运行过程中进行换进、换出,即在进程运行期间,允许将那些暂不使用的代码和数据从内存调至外存的对换区(换出),待以后需要时再将它们从外存调至内存(换进)。甚至还允许将暂时不运行的进程调至外存,待它们重又具备运行条件时再调入内存。
(3)虚拟性。
指能够从逻辑上扩充内存容量,使用户所看到的内存容量远大于实际内存容量。这样,就可以在小的内存中运行大的作业,或者能提高多道程序度。它不仅能有效地改善内存的利用率,还可提高程序执行的并发程度,从而可以增加系统的吞吐量。
虚拟存储器的实现,建立在离散分配内存管理方式的基础上。
虚拟存储器实现方式:
(1) 分页请求系统
分页请求系统是在分页系统的基础上增加了请求调页功能和页面置换功能所形成的页式虚拟存储系统。它允许用户程序只装入少数页面的程序(及数据)即可启动运行。以后,再通过调页功能及页面置换功能陆续地把即将运行的页面调入内存,同时把暂不运行的页面换出到外存上。置换时以页面为单位。为了能实现请求调页和页面置换功能,系统必须提供必要的硬件支持和实现请求分页的软件。
硬件支持:
实现请求分页的软件:
它们在硬件的支持下,将程序正在运行时所需的页面(尚未在内存中的)调入内存,再将内存中暂时不用的页面从内存置换到磁盘上。
(2) 请求分段系统
请求分段系统是在分段系统的基础上,增加了 请求调段 及 分段置换 功能后所形成的段式虚拟存储系统。它允许用户程序只要装入少数段(而非所有的段)的程序和数据即可启动运行。以后通过调段功能和段的置换功能将暂不运行的段调出,再调入即将运行的段。置换是以段为单位进行的。为了实现请求分段,系统同样需要必要的硬件和软件支持。
硬件支持:
软件支持:
请求分页系统每次调入和换出的基本单位都是长度固定的页面,这使得请求分页系统在实现上要比请求分段系统简单(后者在换进和换出时是可变长度的段)。因此,请求分页是目前最常用的一种实现虚拟存储器的方式。
为了实现请求分页,计算机系统除了要求一定容量的内存和外存外,还需要有请求页表机制、缺页中断机构以及地址变换机构。
(1)请求页表机制
请求分页系统中需要的主要数据结构是请求页表,其基本作用仍然是将用户地址空间中的逻辑地址映射为内存空间中的物理地址。为了满足页面换进换出的需要,在请求页表中又增加了四个字段。如下所示:
(1) 状态位(存在位)P:
该字段仅有一位,又称位字。它用于指示该页是否已调入内存,供程序访问时参考。
(2) 访问字段A:
用于记录本页在一段时间内被访问的次数,或记录本页最近已有多长时间未被访问,提供给置换算法(程序)在选择换出页面时参考。
(3) 修改位M:
标识该页在调入内存后是否被修改过。供置换页面时参考。
(4) 外存地址:
用于指出该页在外存上的地址,通常是物理块号,供调入该页时参考。
(2)缺页中断机构
缺页中断是一种特殊的中断,特殊性体现在:
基于这些特征,系统中的硬件机构应能保存多次中断时的状态,并保证最后能返回到中断前产生缺页中断的指令处继续执行。
在为进程分配内存时,涉及到 3 个问题:
(1)最小物理块数的确定
最小物理块数是指能保证进程正常运行所需的最小物理块数,当系统为进程分配的物理块数少于此值时,进程将无法运行。至于进程应获得的最少物理块数,与计算机的硬件结构有关,取决于指令的格式、功能和寻址方式。
(2)内存分配策略
固定分配局部置换(Fixed Allocation,Local Replacement)
固定分配,指为每个进程分配一组固定数目的物理块,在进程运行期间不再改变。局部置换,指如果进程在运行中发现缺页,则只能从分配给该进程的n个页面中选出一页换出,然后再调入一页,以保证分配给该进程的内存空间不变。
可变分配全局置换(Variable Allocation,Global Replacement)
可变分配,指先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少。所谓全局置换,是指如果进程在运行中发现缺页,则将OS所保留的空闲物理块(一般组织为一个空闲物理块队列)取出一块分配给该进程。这样,分配给该进程的内存空间就随之增加。可变分配全局置换这可能是最易于实现的一种物理块分配和置换策略,已用于若干个OS中。
可变分配局部置换(Variable Allocation,Local Replacement)
该策略同样是基于进程的类型或根据程序员的要求,为每个进程分配一定数目的物理块,但当某进程发现缺页时,只允许从该进程在内存的页面中选择一页换出,这样就不会影响其它进程的运行。如果进程在运行中频繁地发生缺页中断,则系统须再为该进程分配若干附加的物理块,直至该进程的缺页率减少到适当程度为止。反之,若一个进程在运行过程中的缺页率特别低,则此时可适当减少分配给该进程的物理块数,但不应引起其缺页率的明显增加。
(3)物理块分配算法
平均分配算法:
即将系统中所有可供分配的物理块平均分配给各个进程。但由于未考虑到各进程本身的大小,可能会造成部分进程很高的缺页率。
按比例分配算法:
即根据进程的大小按比例分配物理块。
考虑优先权的分配算法:
在实际应用中,为了照顾到重要的、紧迫的作业能尽快地完成,应为它分配较多的内存空间。
通常采取的方法是把内存中可供分配的所有物理块分成两部分:一部分按比例地分配给各进程;另一部分则根据各进程的优先权进行分配,
1.何时调入页面
为了确定系统将进程运行时所缺的页面调入内存的时机,可采取预调页策略或请求调页策略,现分述如下。
(1)预调页策略。
将那些预计在不久之后便会被访问的页面预先调入内存。如果预测较准确,那么这种策略显然是很有吸引力的。但遗憾的是,目前预调页的成功率仅约50%。
(2)请求调页策略。
当进程在运行中需要访问某部分程序和数据时,若发现其所在的页面不在内存,便立即提出请求,由OS 将其所需页面调入内存。但这种策略每次仅调入一页,故须花费较大的系统开销,增加了磁盘UO的启动频率。
2.从何处调入页面
将请求分页系统中的外存分为两部分:
通常,由于对换区是采用连续分配方式,而文件区是采用离散分配方式,所以对换区的数据存取(磁盘IO)速度比文件区的高。这样,每当发生缺页请求时,系统应从何处将缺页调入内存,可分成如下三种情况进行:
(1)系统拥有足够的对换区空间。
这时可以全部从对换区调入所需页面,以提高调页速度。为此,在进程运行前,便须将与该进程有关的文件从文件区拷贝到对换区。
(2)系统缺少足够的对换区空间。
这时凡是不会被修改的文件,都直接从文件区调入;而当换出这些页面时,由于它们未被修改,则不必再将它们重写到磁盘(换出),以后再调入时,仍从文件区直接调入。但对于那些可能被修改的部分,在将它们换出时便须调到对换区,以后需要时再从对换区调入。
(3)UNIX方式。
由于与进程有关的文件都放在文件区,故凡是未运行过的页面,都应从文件区调入。而对于曾经运行过但又被换出的页面,由于是被放在对换区,因此在下次调入时应从对换区调入。由于UNIX系统允许页面共享,因此,某进程所请求的页面有可能已被其它进程调入内存,此时也就无需再从对换区调入。
3. 缺页率
假设一个进程的逻辑空间为n页,系统为其分配的内存物理块数为m(m≤n)。如果在进程的运行过程中,访问页面成功(即所访问页面在内存中)的次数为S,访问页面失败(即所访问页面不在内存中,需要从外存调入)的次数为F,则该进程总的页面访问次数为A =S+F,那么:
该进程在其运行过程中的缺页率 f = F / A F/A F/A
通常,缺页率受到以下几个因素的影响:
通常,把选择换出页面的算法称为页面置换算法(Page-Replacement Algorithms)。
置换算法的好坏将直接影响到系统的性能。一个好的页面置换算法应具有较低的页面更换频率。从理论上讲,应将那些以后不再会访问的页面换出,或把那些在较长时间内不会再访问的页面调出。
选择的被淘汰页面将是以后永不使用的,或许是在最长(未来)时间内不再被访问的页面。
采用最佳置换算法通常可保证获得最低的缺页率。但由于人们目前还无法预知,一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但可以利用该算法去评价其它算法。
例题:
假定系统为某进程分配了 3 个物理块,并考虑有以下的页面号引用串:
7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1
该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
该算法实现简单,只需把一个进程已调入内存的页面按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO算法并不能保证这些页面不被淘汰。
页面置换:12次
缺页率: f = F/A = 15/20 = 0.75
LRU置换算法是选择最近最久未使用的页面予以淘汰。
该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t。当需淘汰一个页面时,选择现有页面中其t值最大的,即最近最久未使用的页面予以淘汰。
页面置换:9次
缺页率: f = F/A = 12/20 = 0.60
LRU置换算法的硬件支持
为了知道一个进程在内存中的各个页面各有多少时间未被进程访问,以及如何快速地知道哪一页是最近最久未使用的页面,须有寄存器和栈两类硬件之一的支持。
① 寄存器
为了记录某进程在内存中各页的使用情况,须为每个在内存中的页面配置一个移位寄存器,可表示为
R=Rn-1Rn-2Rn-3…R2R1R0
当进程访问某物理块时,要将相应寄存器的Rn-1位, 值置为1。此时,定时信号将每隔一定时间(例如 100 ms)将寄存器右移一位。如果我们把n位寄存器的数看作是一个整数,那么,具有最小数值的寄存器所对应的页面,就是最近最久未使用的页面。
下图某进程在内存中具有8个页面、为每个内存页面配置一个8位寄存器时的LRU访问情况。这里,把8个内存页面的序号分别定为1~8。由图可以看出,第3个内存页面的R值最小,当发生缺页时,应首先将它置换出去。
② 栈
利用一个特殊的栈保存当前使用的各个页面的页面号。每当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶。因此,栈顶始终是最新被访问页面的编号,而栈底则是最近最久未使用页面的页面号。
假定现有一进程,它分有五个物理块,所访问的页面的页面号序列为:
4,7,0,7,1,0,1,2,1,2,6
在采用LFU算法时,应为在内存中的每个页面设置一个移位寄存器,用来记录该页面被访问的频率。该置换算法选择在最近时期使用最少的页面作为淘汰页。
LFU置换算法的页面访问图,与LRU置换算法的访问图完全相同; 利用这样一套硬件既可实现LRU算法,又可实现LFU算法。但这种算法并不能真正反映出页面的使用情况,因为在每一时间间隔内,只是用寄存器的一位来记录页的使用情况,因此,在该时间间隔内,对某页访问一次和访问1000次是完全等效的。
Clock算法是一种用得较多的LRU近似算法。
(1)简单的Clock置换算法:
为每页设置一位访问位,再将内存中的所有页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位被置1。置换算法在选择一页淘汰时,只需检查页的访问位。如果是0,就选择该页换出;若为1,则重新将它置0,暂不换出,给予该页第二次驻留内存的机会,再按照 FIFO算法检查下一个页面。当检查到队列中的最后一个页面时,若其访问位仍为1,则再返回到队首去检查第一个页面。
由于该算法是循环地检查各页面的使用情况,故称为Clock算法。
但因该算法只有一位访问位,只能用它表示该页是否已经使用过,而置换时是将未使用过的页面换出去,故又把该算法称为最近未用算法或NRU(Not Recently Used)算法。
(2)改进型Clock置换算法:
在将一个页面换出时,如果该页已被修改过,便须将该页重新写回到磁盘上;但如果该页未被修改过,则不必将它拷回磁盘。换而言之,对于修改过的页面,在换出时所付出的开销比未修改过的页面大,或者说,置换代价大。在改进型 Clock 算法中,除须考虑页面的使用情况外,还须再增加一个因素——置换代价。
由访问位A和修改位M可以组合成下面四种类型的页面:
1类(A=0,M=0):表示该页最近既未被访问,又未被修改,是最佳淘汰页。
2类(A=0,M=1):表示该页最近未被访问,但已被修改,并不是很好的淘汰页。
3类(A=1,M=0):表示最近已被访问,但未被修改,该页有可能再被访问。
4类(A=1,M=1):表示最近已被访问且被修改,该页可能再被访问。
在内存中的每个页,都必定是这四类页面之一。
在进行页面置换时,可采用与简单Clock算法相类似的算法,其差别在于该算法须同时检查访问位与修改位,以确定该页是四类页面中的哪一种。其执行过程可分成以下三步:
该算法与简单Clock 算法比较,可减少磁盘的I/O操作次数。但为了找到一个可置换的页,可能须经过几轮扫描。实现该算法本身的开销将有所增加。
在请求分页系统中,进程在运行时页面换进换出所付出的开销将对系统性能产生重大的影响。
1.影响页面换进换出效率的若干因素
2. 页面缓冲算法 PBA
以VAX/VMS操作系统中所使用的页面缓冲算法为例。在该系统中,内存分配策略上采用了可变分配和局部置换方式,系统为每个进程分配一定数目的物理块,系统自己保留一部分空闲物理块。为了能显著地降低页面换进、换出的频率,在内存中设置了如下两个链表:
1. 空闲页面链表
该链表是系统掌握的空闲物理块链表,用于分配给频繁发生缺页的进程,以降低该进程的缺页率。当这样的进程需要读入一个页面时,便可利用空闲物理块链表中的第一个物理块来装入该页。当有一个未被修改的页要换出时,把它们所在的物理块挂在空闲链表的末尾。如果以后某进程需要这些页面中的数据时,便可从空闲链表上将它们取下,免除了从磁盘读入数据的操作,减少了页面换进的开销。
2. 修改页面链表
它是由已修改的页面所形成的链表。设置该链表的目的是为了减少已修改页面换出的次数。当进程需要将一个己修改的页面换出时,系统并不立即把它换出到外存上,而是将它所在的物理块挂在修改页面链表的末尾。这样做的目的是:降低将已修该页面写回磁盘的频率,降低将磁盘内容读入内存的频率。
PBA算法的主要特点是:
横轴N: 多道程序的数量
纵轴:处理机的利用率
产生“抖动”的原因:
发生“抖动”的根本原因是:同时在系统中运行的进程太多,由此分配给每一个进程的物理块太少,不能满足进程正常运行的基本要求,致使每个进程在运行时,频繁地出现缺页,必须请求系统将所缺之页调入内存。这会使得在系统中排队等待页面调进/调出的进程数目增加。显然,对磁盘的有效访问时间也随之急剧增加,造成每个进程的大部分时间都用于页面的换进/换出,而几乎不能再去做任何有效的工作,从而导致发生处理机的利用率急剧下降并趋于0的情况。我们称此时的进程是处于“抖动”状态。
所谓工作集,是指在某段时间间隔Δ 里,进程实际所要访问页面的集合。Denning 指出,虽然程序只需要少量的几页在内存便可运行,但为了较少地产生缺页,应将程序的全部工作集装入内存中。然而我们无法事先预知程序在不同时刻将访问哪些页面,故仍只有像置换算法那样,用程序的过去某段时间内的行为作为程序在将来某段时间内行为的近似。具体地说,是把某进程在时间t的工作集记为w(t,Δ ),其中的变量Δ称为工作集的“窗口尺寸”
由此可将工作集定义为,进程在时间间隔(t-Δ,t)中引用页面的集合。
工作集w(t, Δ )是二元函数,即在不同时间 t 工作集大小不同,所含的页面数也不同;工作集与窗口尺寸Δ有关,是窗口尺寸Δ的非降函数。
即:w(t,Δ)⊆w(t,Δ+1)
采用调节多道程序度来控制“抖动”发生。
请求分段式虚拟存储器系统,是以分段为单位进行换入、换出的。在请求分段系统中,程序运行之前,只需先调入少数几个分段(不必调入所有的分段)便可启动运行。当所访问的段不在内存中时,可请求OS 将所缺的段调入内存。像请求分页系统一样,为实现请求分段存储管理方式,同样需要一定的硬件支持和相应的软件。
1. 请求段表机制
2. 缺页中断机构
由于段不是定长的,因此对缺段中断的处理要比对缺页中断的处理复杂。
3. 地址变换机构
分段存储管理方式的优点是便于实现分段的共享与保护。为了实现分段共享,还应配置相应的数据结构——共享段表,以及对共享段进行操作的过程。
(1) 共享进程计数count。
记录有多少进程正在共享该分段。当某进程不再需要而释放它时,系统并不立即回收该段所占内存区,而是检查count是否为0,若不是0,则表示还有进程需要它,仅当所有共享该段的进程全都不再需要它时,此时count 为0,才由系统回收该段所占内存区。
(2) 存取控制字段。
对于一个共享段,应为不同的进程赋予不同的存取权限。
(3) 段号。
对于一个共享段,在不同的进程中可以具有不同的段号,每个进程可用自己进程的段号去访问该共享段。
2. 共享段的分配与回收
了解即可
3. 分段保护
(1)越界检查
越界检查是利用地址变换机构来完成的。
(2)存取控制检查
存取控制检查是以段为基本单位进行的。
(3)环保护机构
在该机制中规定:
低编号的环具有高优先权。OS核心处于0号环内;某些重要的实用程序和操作系统服务占居中间环;而一般的应用程序,则被安排在外环上。在环系统中,程序的访问和调用应遵循以下规则:
所学课本:
计算机操作系统 第四版(汤小丹等)西安电子科技大学出版社
王道操作系统复习指导(王道论坛)电子工业出版社