存储管理(五)

存储管理(五)

内存也称主存,是指CPU能直接存取指令和数据的存储器。硬盘、软盘和磁带等存储器,一般称为外存或辅存。内存是现代计算机系统进行操作的中心。内存是一个大型的、由字或字节构成的一维数组,每个单元都有自己的地址。对内存的访问是通过一系列对指定地址单元进行读或写来实现的。例如,一条典型指令的执行周期是,首先从内存中取出指令,计算操作数据的有效地址,并映像为物理地址,按照该地址对内存进行存取,然后对数据实施指定的操作。

用户使用内存的过程是将源程序经过一系列操作,主要处理阶段为编辑、编译、连接、装入和运行。由于用户程序经过编译后每个目标模块都以0为基地址顺序编址,这种地址称为相对地址逻辑地址;内存中各物理存储单元的地址是从统一的基地址开始顺序编址的,这种地址称为绝对地址逻辑地址

重定位和对换技术

如果所有的程序都将把物理地址写死在程序的话,并不符合操作系统对资源的管理这一功能。所以当我们把程序加载到内存时,需要进行地址转换,也就是把逻辑地址转换成物理地址,这样操作系统才能真正从内存中拿到程序的数据执行逻辑等。地址转换又称重定位。对程序进行重定位的技术按重定位的时机可分为静态重定位和动态重定位两种

静态重定位

静态重定位是在目标程序装入内存时,由装入程序对目标程序中的指令和数据的地址进行修改,即把程序的逻辑地址都改成实际的内存地址。对每个程序来说,这种地址变换只是在装入时一次完成,在程序运行期间不再进行重定位。

静态重定位的优点是无需增加地址转换机构,便于实现程序的静态链接。在早期计算机系统中大多采用这种方案。它的主要缺点是:

  • 程序的存储空间只能是连续的一片区域,而且重定位之后不能再移动,这不利于内存空间的有效使用。
  • 各个用户进程很难共享内存中的同一程序的副本。
动态重定位

动态重定位是在程序执行期间,每次访问内存之前进行重定位。就是说,进程装入内存后,其内存空间中的内容与地址空间中的内容一样。即:将该进程的程序和数据原封不动地装入内存中。当调度该进程在CPU上执行时,才进行相关地址的重定位。

动态重定位经常用硬件实现。所需的硬件支持包括一对寄存器:一个存放用户程序在内存的起始地址,称作基址寄存器;另一个存放用户程序逻辑地址的最大范围,称作限长寄存器。例如,某进程(进程3)装入内存的起始地址是64k,其大小是24kb。当进程3执行时,操作系统自动将该进程在内存的起始地址放入基址寄存器中,把其大小(24kb)放入限长寄存器中。

动态重定位的主要优点是:

  • 程序占用的内存空间动态可变,不必连续存放在一处。
  • 比较容易实现几个进程对同一程序副本的共享使用。
对换技术

早期的对换技术用于单用户系统。其思想是:除操作系统占用的内存空间外,所剩余的全部内存只供一个用户进程使用,其他进程都放在外存上。每次只调入一个进程进入内存运行。当这个进程用完分给它的时间后,这个进程就放到外存上。系统再把另一个进程调入内存,让它运行一个时间片的时间,如此轮转。

在多道程序环境中也可以采用对换技术。此时,内存中保留多个进程。当内存空间不足以容纳要求进入内存的进程时,系统就把内存中暂时不能运行的进程(包括程序和数据)换出到外存上,腾出内存空间,把具备运行条件的进程从外存换入到内存中。

如果创建进程时,其大小固定且以后不再改变,那么,只需要根据所需要的大小进行分配即可。如果进程的数据段可以动态增长,那么,就涉及到该进程相邻的内存区是否空闲的问题。如果空闲,就把该空闲区分配给这个进程,满足其增长的需要;若相邻区不空闲,正被别的进程占用,那么该进程只好移到另一个有足够大空间的空闲区中,或者把一个或多个进程换出,以满足该进程的扩充需求。如果系统中大部分进程在运行时都要增长,就可以在换入或移动进程时为它分配一些额外的内存空间。当换出它时,只把进程实际使用的内存空间中的内容换到盘上。

分区法

分区分配是为支持多道程序运行而设计的一种最简单的存储管理方式。在这种方式下,除操作系统占用内存的某个固定分区(通常是低址部分)外,把其余内存供用户程序使用,并且划分成若干分区,每个分区里容纳一个作业。按照分区的划分方式,可分为固定分区法和动态分区法两种常见的分配方法。

固定分区法

固定分区就是内存中分区的个数固定不变,各个分区的大小也固定不变,但不同分区的大小可以不同。每个分区只可装入一个进程。

划分分区大小有两种方式:一种是等分方式,即各分区都有同样大小;另一种是差分方式,即不同分区有不同大小。等分方式有明显的缺点,如浪费大,可能无法装入大程序等。所以,实际运行的系统大多采用差分方式,即有些分区容量较小,适于存放小程序;有些分区容量较大,适于存放大程序。

为了便于内存分配,系统建立一张分区说明表。每个分区对应表中的一项。各表项包含每个分区的起始地址、分区大小以及状态。

当某个用户进程要装入内存时,向系统提出分配内存的申请,同时给出需要的内存空间是多大。系统按照用户的申请表去检索分区说明表,从中找出一个能满足要求的,并且是空闲(即未使用)的分区,将它分给该进程,然后修改分区说明表项的状态栏,即把状态置为“正使用”。如果找不到大小足够的分区,则拒绝为该用户进程分配内存。

当一个用户进程执行完,不再使用分给它的分区,就释放相应的内存空间。系统根据分区始址或分区号在分区说明表中找到相应的表项,把它的状态改为“未使用”

固定分区法管理方式简单,所需操作系统软件和处理开销都小。它的缺点是:

  • 内存空间利用率不高,有时浪费情况会相当严重,即存在碎片问题。
  • 要在系统生成时指定分区的个数,这就限制了系统中处于活动状态的进程数目;另外,在多数情况下,并不能预先知道所有作业对内存的需求,而分区大小是在系统生成时确定的。
动态分区法

由于用户进程大小不可能预先规定,而且进程到来的分布情况也无法预先确定,所以固定分区法中分区的大小不会总与进程大小相符。为了解决内存浪费问题,可把分区的大小和个数设计成可变的。就是说,各个分区是在相应进程要进入内存时才建立的,使其大小恰好适应进程的大小。这种技术称为动态分区法。

当进程请求内存时,如果找到一个分区比所需内存大,就将该分区一分为二,在分区分配表中新增一个表项,修改原来的表项。如果进程释放,则在对应的表项上标记“空闲”,如果释放的分区恰好与其他空闲区相邻接,则系统还要将它们合并起来,相应的表项也要归并。

为了使用分区分配,系统要设置相应的数据结构来记录内存的使用情况。常用的数据结构有:空闲分区表,空闲分区链。

分配算法:最先适应算法,从上往下查找表,只要找到第一个满足要求的空闲分区就停止查找。最佳适应算法,找到一块内存,满足该内存大小>=请求内存大小。循环适应算法、这种算法是最先适应算法的变形,与其不同的是,该算法不从头开始找,而是从上次找到的位置开始往下找,取第一个满足的。

内存碎片:依据碎片出现的位置,分为内部碎片和外部碎片两种。在一个分区内部出现的碎片称作内部碎片,如固定分区法产生内部碎片。在所有分区之外新增的碎片称作是外部碎片,如在动态分区法实施过程中出现的越来越多的小空闲分区,由于它们太小,无法装入一个小进程,因而被浪费掉。

分页技术

无论是分区技术还是对换技术,都要求把一个进程放置在一片连续的内存区域中,从而造成内存中出现碎片问题。解决这个问题通常有两种办法:一种是内存紧缩法——通过移动信息,使空闲区变成连续的较大的一块,从而得以利用,但这要花费很多CPU时间;另一种是分页管理——它允许程序的存储空间不一定连续,这样,可把一个程序分散地放在各个空闲的内存块中,它既不需要移动内存中原有的信息,又解决了外部碎片问题,从而提供了内存的利用率。

分页存储管理的基本概念

逻辑空间分页:将一个进程的逻辑地址空间划分成若干大小相等的部分,每个部分称作页面或页。每页都有一个编号,叫做页号。

内存空间分页:把内存等分成与页面大小相同的若干存储空间,称作内存块或页框。依次编号。

逻辑地址表示:在32位系统中011位表示页内地址,即每页的大小为4KB;1232位为页号,表示地址空间中最多可容纳2^20个页面。

在分页情况下,系统以块为单位把内存分给各个进程,进程的每个页面对应一个内存块,并且一个进程的若干页可以分布装入物理上不连续的内存块中。当把一个进程装入内存时,首先检查它有多少页。如果有n页,则至少应有n个空闲块才能装入该进程。如果满足要求,则分配n个空闲块,把它装入,且在该进程的页表中记下各页面对应的内存块号。

在分页系统中,允许将进程的各页面离散地装入内存的任何空闲块中,这样就出现进程的页号连续、而块号不连续的情况。怎样找到每个页面在内存中对应的物理块呢?为此,系统为每个进程设立一张页面映像表,简称页表。页表的作用主要是实现从页号到物理块号的地址映射。

操作系统管理整个内存,它必须知道哪些块已经分出去了,哪些块还是空闲的,总共有多少块等物理存储的情况。这些信息保存在称作内存块表的数据结构中,整个系统有一个内存块表。每个内存块在内存块表中占一项,表明该块当前空闲还是已经分出去了,如果分出去了,是分给哪个进程的哪个页面了。

分页系统中的地址映射

当进程需要访问某个逻辑地址中的数据时,分页地址映像硬件自动按页面大小将CPU得到的有效地址(相对地址)分成两部分:页号和页内地址(p,d)。以页号p为索引去检索页表。这种查找操作由硬件自动进行。从页表中得到该页的物理块号,把它装入物理地址寄存器中,同时,将页内地址d直接送入物理地址寄存器的块内地址字段中。这样,物理地址寄存器中的内容就是由二者拼接成的实际访问内存的地址,从而完成从逻辑地址到物理地址的转换。

可以看出,分页本身就是动态重定位形式。由分页硬件机构把每个逻辑地址与某个物理地址关联在一起。

多级页表

对于逻辑地址空间32位表示的系统,页面大小为4KB,那么每个进程的页表中就有高达2^20个表项,设每个表项占4B,每个进程仅页表就要占用4MB的内存,而且必须使连续的。这显然是不现实的。解决此问题的简单方法是把页表分成若干较小的片段,离散地存放在内存中,并且只将当前需要的部分表项调入内存,其余的页表项根据需要动态地调入内存。

一种方法是利用两级页表,即把页表本身也分页,使每个页面的尺寸与物理内存块的大小相同,并且按序为这些页面编号0~n。例如,在32位机器上,页面大小为4KB。这样,表示逻辑地址的页号就占用20位,页面地址占用12位。把页表也分页,每个页表占4B,于是页号就分为两部分:高10位表示外层页号,低10位表示内存页号。

在这里插入图片描述

其中,p1是访问外层页表的索引,外层页表中的每一项是相应内层页表的起始地址;p2是访问内层页表的索引,其中的表项是相应页面在内存中的物理块号。

在具有两级页表结构的系统中,地址转换的方法是:利用外层页号p1检索外层页表,从中找到相应内层页表的基址;再利用p2作为该内层页表的索引,找到该页面所在内存的块号;用该块号和页内地址d拼接起来,形成访问内存的物理地址。

散列页表

处理大于32位地址空间的通用方式是使用散列列表,以页号作为参数形成散列值。散列表中每一项有一个链表,它把有相同散列值的元素链接起来。每个链表元素由三部分组成:页号、对应的内存块号、指向链表中下一个元素的指针。

地址转换过程是:以逻辑地址中的页号p作为散列函数的参数,得到一个散列值;以它作为检索散列表的索引;把逻辑页号p与相应链表的第一个元素内表示页号的字段进行比较,如果匹配,则将相应的内存块号与逻辑地址中的页内地址拼接起来,形成访问内存的物理地址;如果二者不匹配,就沿着链表指针向下搜索,直至找到匹配的页号。

倒置页表

为了减少页表占用过多内存空间,可以采用倒置页表。倒置页表的构造恰好与普通页表相反,它是按内存块号排序的,每个内存块占有一个表项。每个表项包括存放在该内存块中页面的虚拟页号和拥有该页面的进程标识符。这样,系统中只有一个页表,每个内存块对应唯一的表项。

利用倒置页表进行地址转换的过程是:系统中每个虚拟地址由进程标识符pid,虚拟页号p和页内地址d三部分组成,每个倒置页表的表项由进程标识符pid和虚拟页号p组成。当需要访问地址时,就用进程标识符和页号去检索倒置页表。如果找到与之匹配的表项,则该表项的序号i就是该页在内存中的块号,块号i与逻辑地址中的页内地址d拼接起来就构成访问内存的物理地址;如果搜索完整个页表都没有找到相匹配的页表项,则表示发生了非法地址访问——此页目前尚未调入内存。对具有请求调页功能的存储管理系统,应产生请求调页中断;若没有此功能,则表示地址有错。

倒置页表可减少页表占用的内存,却增加了检索页表时所耗费的时间,或许要查完整个页表才能找到匹配项。为了解决这个问题,可以采用散列页表,即用一个简单的散列函数将虚拟地址的页号映射到散列表,散列表项中包括指向倒置页表的指针。这样,可把搜索工作限定在一个页表项或多个页表项上。当然,对散列表的访问页增加了访问内存的次数;一次是访问散列页表,另一次是访问倒置页表。为了改善性能,倒置页表可以和快表一起使用。

分段技术

在前面介绍的各种存储管理技术中,提供给用户的逻辑地址空间是一维的线性空间。这与内存的物理组织基本相同,但用户所写程序的逻辑结构却不是这样的。通常,用户程序由若干程序模块和数组模块组成,各有自己的名字,实现不同的功能,它们有不同的大小。例如,一个C程序有一个主函数main,它调用3个子函数f1,f2,f3,又调用标准库函数printf和scanf。我们希望这个程序的的地址空间按照自身的逻辑关系划分为若干段,例如每个函数一个段,各段单独占用一片内存空间。这样,程序在内存中的存放情况就与我们知道的程序的逻辑结构对应起来了。另外,把程序和数据分隔为逻辑上独立的地址空间,有助于存储共享和保护。为了满足程序员在编程和使用等方面的需求,引入了分段存储管理技术。

由于整个进程的地址空间分成多个段,所以逻辑地址要用两个成分来表示:段号s和段内地址d。就是说,在分段存储情况下,进程的逻辑地址空间是二维的。

在这里插入图片描述

在分段存储管理中,内存以段为单位进行分配,每段单独占用一块连续的内存分区。各分区的大小由对应段的大小决定。这类似于动态分区分配方式,但二者是不同的。在分段存储管理系统中,一个作业或进程可以有多个段,这些段可以离散地放入内存的不同分区中。就是说,一个作业或进程的各段不一定放在彼此相邻的分区中。

段页式技术

分页存储管理能够有效地提高内存利用率,而分段存储管理能够很好地满足用户需要。把这两种管理技术有机地结合起来,“各取所长”,就形成新的存储管理系统——段页式存储管理系统。

段页式存储管理的基本原理
  • 等分内存。把整个内存分为大小相等的内存块,内存块从0开始依次编号。
  • 进程的地址空间采用分段方式。把进程的程序和数据划分为若干段,每段有一个段名。
  • 段内分页。把每段划分成若干页,页面的大小与内存块相同。每段内的各个页面都分别从0开始依次编号。
  • 逻辑地址结构。一个逻辑地址表示由三部分组成:段号s、页号p和页内地址d,记作 v = (s,p,d)
  • 内存分配。内存的分配单位是内存块。
  • 段表、页表和段表地址寄存器。为了实现从逻辑地址到物理地址的转换,系统要为每个进程建立一个段表,还要为该进程段表中的每段建立一个页表。这样,进程段表的内容不再是段长和该段在内存的起始地址,而是页表长度和页表地址。为了指出运行进程的段表地址,系统有一个段表地址寄存器,它指出进程的段表长度和段表起始地址。

在段页式存储管理系统中,面向用户的地址空间是段式划分,而面向物理实现的地址空间是页式划分。就是说,用户程序逻辑上划分为若干段,每段又分成若干页面。内存划分成对应大小的块。进程映像对换是以页为单位进行的,使得逻辑上连续的段存放在分散的内存块中。

虚拟存储器

所谓虚拟存储器是用户能作为可编址内存对待的虚拟存储空间,它使用户逻辑存储器与物理存储器分离,是操作系统给用户提供的一个比真实内存空间大得多得地址空间。就是说,虚拟存储器并不是实际的内存,它的大小比内存空间大得多;用户感觉所能使用的“内存”非常大,这是操作系统对逻辑内存的扩充。

实现虚拟存储技术的物质基础是二级存储器结构和动态地址转换机构(DAT)。经过操作系统的改造,将内存和外存有机地联系在一起,在用户面前呈现一个足以满足编程需要的特大内存空间,这就是所谓单级存储器的概念。

虚拟存储器实质上是把用户地址空间和实际的存储空间区分开来,当做两个不同的概念。动态地址转换机构在程序运行时把逻辑地址转换成物理地址,以实现动态定位。

虚拟存储器的特征:虚拟扩充、部分装入、离散分配、多次对换

请求分页技术

请求分页存储管理技术是在单纯分页技术基础上发展起来的,二者的根本区别在于请求分页提供虚拟存储器。它的思想是:当一个进程的部分页面在内存时就可调度它运行;在运行过程中若用到的页面尚未在内存,则把它们动态换入内存。这样,就减少了对换时间和所需内存数量,允许增加程序的道数。为了标示进程的页面是否已在内存,在每个页表项中增加一个标志位,其值为1表示该页已在内存,其内存块可以访问;其值为0表示该页尚未装入内存,不能立即进行访问。

如果地址转换机构遇到一个具有标志位为0的页表项时,便产生一个缺页中断,高速CPU当前要访问的这个页面还未装入内存,这不是用户程序的错误。操作系统必须处理这个中断,即装入所要求的页面,相应调整页表的记录,然后再重新启动该指令。由于这种页面是根据请求而被装入的,所以这种存储管理方法也叫做请求分页存储管理。通常在进程最初投入运行时,仅把它的少量几页装入内存,其他各页是按照请求顺序动态装入的。这就保证用不到的页面不会被装入内存。

硬件支持及缺页处理

为了实现请求分页,系统必须提供一定的硬件支持,除了需要一定容量的内存和外存,以及支持分页机制外,还需要有页表机制、缺页中断机构及地址转换机构。

缺页中断的处理过程是由硬件和软件共同实现的。

在这里插入图片描述

可以看出,上半部分是硬件指令处理周期,由硬件自动实现,它是最经常执行的部分。下半部是由操作系统中的中断处理程序实现的,处理之后再转入硬件周期中。软件和硬件的关系如此密切,以至于在有些实验性系统中用硬件机构来实现上述软件功能。

页面置换算法

页面置换

如果被访问的页不在内存时,则产生缺页中断。操作系统进行中断处理,把该页从外存调入内存。那么新调进的页到底放在什么地方呢?如果内存中有空闲块,则可把该页装入任何空闲块中,调整页表项及存储分块表。如果当前内存空间已装满,那么该页放到哪里去呢?此时必须先淘汰已在内存的一页,腾出空间,再把所需页面装入。页面置换主要包括四个步骤:

  • 找出所需页面再磁盘上的位置
  • 找出一个空闲内存块。如果有空闲块,就用它;如果没有空闲块,就用页面置换算法选择一个置换的内存块。把该置换的页写到磁盘上,并相应修改页表和存储块表。
  • 把所需页面读入内存块(刚刚得到的空闲块),修改页表和存储块表。
  • 重新启动该用户进程。

可见,如果内存中没有空闲块可用,就要发生两次页面传送(换出和换入),这样使缺页处理时间加倍,相应增加了有效存取时间。利用页表项中的修改位,可以适当减少这种开销。因为选中一页进行置换时,如果它的修改位没有设置,就不必把它在内存块中的内容写回盘上。

实现请求分页必须解决内存块的分配算法和页面置换算法两个主要问题。如果有多个进程在内存,必须决定为每个进程分配多少内存块;另外,当需要置换页面时,必须确定淘汰哪个内存块。

先进先出法(FIFO)

最简单的页面置换算法是先进先出法。这种算法总是淘汰在内存中停留时间最长(年龄最老)的一页,即先进入内存的页,先被换出。其理由是:最早调入内存的页不再被使用的可能性要大于刚调入内存的页。当然,这种理由并不很充分。把一个进程所有在内存中的页按进入内存的次序排队,淘汰页面总是在队首进行。如果一个页面刚被放入内存,就把它插在队尾。

FIFO页面置换算法的优点是容易理解且方便程序设计。然而,它的性能并不很好。仅当按线性顺序访问地址空间时,这种算法才是理想的;否则,效率不高。因为那行常被访问的页,往往在内存中停留很久,结果它们因变“老”而不得不淘汰出去。

最佳置换法(OPT)

最佳置换算法是1966年由Belady提出的一种算法。其实质是:为调入新页面必须预先淘汰某个老页面时,所选择的老页面应在将来不被使用,或者是在最远的将来才被访问。采用这种算法,能保证有最小缺页率。

OPT算法在实现上有困难,因为它需要预先知道一个进程整个运行过程中页面走向的全部情况。不过,这个算法可用来衡量其他算法的优劣。

最近最久未使用置换法(LRU)

最佳置换算法在实际中行不通,但可以找到与它接近的算法。先进先出算法(FIFO)和最佳算法(OPT)之间的主要差别是,FIFO算法将页面进入内存后的时间长短作为淘汰依据,而OPT算法是依据今后使用页面的时间。如果以“最近的过去”作为“不久的将来”的近似,就可以把最近最长一段时间里不曾使用的页面淘汰掉。它的实质是:当需要置换一页时,选择在最近一段时间里最久没有使用过的页面予以淘汰。这种算法称为最近最久未使用算法(LRU)。

实现LRU算法必须有大量硬件支持,同时需要一定的软件开销。所以,实际实现的都是一种简单有效的LRU近似算法。

最近未使用置换法(NRU)

最近未使用置换法的基本思想是由系统统计哪些页面最近使用过,哪些页面未使用,对未使用的页予以淘汰。为此,在页表项中设置两个状态位,即引用位R和修改位M,每次访问内存时要更新这些位,由硬件设置它们。一旦某位被置为1,就一直保留为1,直至操作系统把它重新置为0。

当启动一个进程时,它所有页的引用位和修改位都由操作系统置为0。引用位被定期清0。每次访问内存时,该页的引用位就置1。这样,通过检查引用位就可确定哪些页最近使用过,哪些页自上次置0以后还未使用过。

当发生缺页时,操作系统检查所有的页面,并根据它们当前的引用位和修改位的值,把它们分为如下四类。

  1. 最近未访问过,未修改(值为00)
  2. 最近未访问过,已修改(值为01)
  3. 最近访问过,未修改(值为10)
  4. 最近访问过,已修改(值为11)

第3类页面的引用位被时钟中断清0后就成为第1类。而修改位并不被时钟中断清除,该位作为今后是否写回磁盘的一个条件。

第二次机会置换法(SCR)

第二次机会置换法是对FIFO算法的改进——避免把经常使用的页面置换出去。该算法的思想基本上与FIFO相同。当选择某一页面置换时,就检查最老页面的引用位:如果是0,就立即淘汰该页;如果该引用位是1,就给它第二次机会,将引用位清0,并把它放入页面链表的末尾,把它的装入时间重置为当前时间;然后选择下一个FIFO页面,这样,得到第二次机会的页面将不被淘汰,直至所有其他页面都被置换过(或者给了第二次机会)。因此,如果一个页面经常使用,它的引用位总保持1,那么它就不会被淘汰。

时钟置换法(Clock)

时钟置换法既是对第二次机会法的改进,也是对LRU算法的近似。它避免采用第二次机会法需要页面在链表中移动所带来的效率问题。具体办法:把所有页面保存在一个类似钟表表盘的环状链表中,由一个指针指向最老的页面。

当发生缺页时,首先检查指针指向的页面,如果它的引用位是0就淘汰该页,且把新页面插入这个位置,然后把指针向前移一个位置;如果引用位是1就清0,且把指针前移一个位置;重复这个过程,直至找到引用位为0的页面为止。

最少使用置换法(LFU)

最少使用页面置换算法是基于访问计数的页面置换法。该算法要为每个页面设置一个软件计数器,用于记载该页被访问的次数,其初值为0。在每次时钟中断时,操作系统扫描内存中的页面,将每页的引用位R的值加到对应的计数器上。这个计数器可粗略反映各页被访问的频繁程度。发生缺页时,淘汰其计数值最小的页。

一般计数方式会出现如下主要问题:某些页面在进程刚开始时频繁使用,而后不再使用,其计数器的值一直保持很大,因而操作系统将淘汰有用的页面而不是后面不再使用的页面。

页面缓冲算法(PB)

页面缓冲算法是对FIFO简单置换算法的改进。该算法维护两个链表:一个是空闲页链表,另一个是修改页链表。空闲页链表其实是页面内存块链表,直接用于读入页面;修改页链表是由修改页面的内存块构成的链表。

当发生缺页时,按照FIFO算法选取一个淘汰页,并不是抛弃它,而是把它放入两个链表中的一个。如果该页未被修改,就放入空闲页链表中;否则,把它放入修改页链表中。注意,此时页面在内存中并不做物理上的移动,只是将页表中的表项链入上述两个链表之一。需要读入的页面装入空闲页链表中的第一个内存块,使得该进程尽快地重新启动。不必等待淘汰页面被写出去。当淘汰页以后要写出去时,也只是把该页的内存块链入空闲页链表的末尾。类似地,当选中的淘汰页为已修改页面时,也把该页的内存块链入修改页链表的末尾。

当发生缺页时,按照FIFO算法选取一个淘汰页,并不是抛弃它,而是把它放入两个链表中的一个。如果该页未被修改,就放入空闲页链表中;否则,把它放入修改页链表中。注意,此时页面在内存中并不做物理上的移动,只是将页表中的表项链入上述两个链表之一。需要读入的页面装入空闲页链表中的第一个内存块,使得该进程尽快地重新启动。不必等待淘汰页面被写出去。当淘汰页以后要写出去时,也只是把该页的内存块链入空闲页链表的末尾。类似地,当选中的淘汰页为已修改页面时,也把该页的内存块链入修改页链表的末尾。

利用这种方式可使被淘汰页当时还留在内存中。这样,当进程又访问该页时,只需花费较少的开销就使它回到该进程的驻留集(进程在内存映像的集合)中,不需要进行输入/输出。当修改页链表中的页数达到一定数量时,就把它们一起写回磁盘,而不是一次一页操作。这就显著地减少了磁盘I/O操作的次数和磁盘存取时间。事实上,这两个链表起到了页面缓存的作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值