322_请求分页管理方式
# 3.2_2_请求分页管理方式
各位同学大家好,在这个小节中我们会学习请求分页管理方式相关的一系列知识点。
那么通过上个小节的学习,我们知道请求分页管理方式是在基本分页管理方式的基础上进行拓展,从而实现的一种虚拟内存管理技术。
相比于基本分页存储管理,操作系统还需要新增两个最主要的功能,第一个功能就是请求调页的功能,系统需要判断一个页面是否已经调入内存,如果说还没有调入内存,也就是页面缺失的话,那么还需要将页面从外存调到内存当中,这是请求调页功能。
第二个需要提供的功能是页面置换功能,就是当内存暂时不够用的时候,需要决定把哪些页面换出到外存。
针对于这两个功能如何实现,我们会介绍在请求分页管理方式当中,页表机制与基本分页存储管理方式当中有哪些相同和不同的地方。
另外为了实现请求调页的功能,请求分页管理系统当中引入了缺页中断机构,
最后我们会介绍在这种管理方式当中,地址变换到底是什么样一个过程,在学习小节的时候需要注意和基本分页存储管理方式进行一个对比。
# 页表机制
首先我们来看一下请求分页管理方式和基本分页存储管理方式的页表机制有哪些相同和不同的地方。我们还是从如何实现页面置换和请求调页这两个功能的角度出发,来分析页表机制应该怎么设计。
首先与基本分页存储管理相比,为了实现请求调页,那么操作系统肯定需要知道每个页面是否已经调入内存,如果这个页面还没有掉入的话,那么也需要知道这个页面在外存当中存放的位置。所以为了知道这些信息,那么肯定需要把这些信息记录在某种数据结构当中,页表其实就是一个很好的地方。
另外为了实现页面置换功能,那么操作系统肯定需要通过某种规则来决定到底是把哪个页面换出到外存,所以我们需要记录每个页面的一些指标,然后操作系统根据这个指标来决定你换出哪一页。另外如果说一个页面在内存当中没有被修改过,那么这个页面其实换出外存的时候不用浪费时间再写回外存,因为它没有修改过,所以外存当中保存的副本其实和内存当中的数据是一模一样的,只有页面修改过的时候,才需要把它换到外存当中,把以前旧的数据覆盖,所以操作系统也需要记录各个页面是否被修改这样的信息。
因此相比于基本分页的页表来说,请求分页存储管理的页表增加了这样的 4 个字段。
第一个是状态位,状态位就是用于表示此时这个页面到底是不是已经掉入内存了。比如说在这个表当中,0 号页面的状态位置零表示 0 号页面暂时还没有调入内存,那一号页面的状态位是一表示一号页面此时已经在内存当中了。
第二个新增的数据是访问字段,操作系统在置换页面的时候,可以根据访问字段的这些数据来决定到底要换出哪一个页面,所以我们可以在访问字段当中记录每个页面最近被访问过几次,我们可以选择把访问次数更少的那些页面换出外存,或者我们也可以在访问字段当中记录我们上一次访问这个页面的时间,这样的话我们可以实现优先的换出很久没有使用的页面这样的事情,所以这是访问字段的功能。
第三个新增的数据是修改位用来标记这个页面在调入内存之后是否被修改过,因为没有被修改过的页面是不需要再写回外存的,那不写回外存的话就可以节省时间。
第四个需要增加的数据,各个页面在外存当中存放的位置
这是请求分页存储管理方式当中的页表新增的 4 个字段,在有的地方也会把右边的页表称为请求页表,然后左边的页表称为基本页表或者简称页表,这是请求分页存储管理当中页表机制产生的一些变化,新增的东西,这也是实现请求调页和页面置换的一个数据结构的基础。
# 缺页中断机构
为了实现请求调阅功能,系统当中需要引入缺页中断机构,我们直接来结合一个例子来理解去中断机构工作的一个流程。
假设在一个请求分页的系统当中要访问一个逻辑地址,页号为 0,页内偏移量为 1024。那么为了访问这个逻辑地址,需要查询页表,缺页中断机构会根据对应的页表项来判断此时这个页面是否已经在内存当中,如果说没有在内存当中,也就是这个状态位为 0 的话,那么会产生一个缺页中断信号,之后操作系统的缺页中断处理程序会负责处理这个中断。由于中断处理的过程需要 IO 操作,把页面从外存调入内存,所以在等待 IO 操作完成的过程当中,之前发生缺页的进程应该被阻塞放入到阻塞队列当中,只有调页的事情完成之后,才把它再唤醒,重新放回就绪队列。
通过页表项就可以知道页面在外存当中存放在什么地方。如果说此时内存当中有空闲的快,比如说 a 号块空闲的话,那就可以把空闲快分配给此时缺页的进程,再把目标页面从外存放到内存当中,相应的也需要修改页表项当中对应的一些数据,这是第一种情况,就是有空闲的内存快的情况。
第二种情况,如果说此时内存中没有空闲块的话,那么需要由页面置换算法,通过某种规则来选择要淘汰一个页面,比如说页面置换算法选中了要淘汰二号页面,由于二号页面的内容是被修改过的,所以二号页面的内容需要从内存再写回外存,把外存当中的旧数据覆盖掉,这样的话2 号页面,以前占有的 c 号块就可以空出来,让 0 号页面使用了,于是可以把 0 号页面从外存调入内存当中的 c 号块,相应的我们也需要把换出外存的页面,还要换入内存的页面,相应的那些数据给更改。这是第二种情况,就是内存当中没有空隙块的时候,需要用页面置换算法淘汰一个页面
缺页中断的发生肯定和当前执行的指令是有关的。由于指令想要访问某一个逻辑地址,而系统又发现这个逻辑地址对应的页面还没有调入内存,因此才发生了缺页中断。由于它和当前执行的指令有关,因此缺页中断是属于内中断的。还记得咱们之前讲的内中断和外中断的分类吗?内中断可以分为陷阱、故障还有中指这样三种类型,其中故障这种内中断的类型是指有可能被故障处理程序修复的,比如说缺页中断这种异常的情况是有可能被操作系统修复的,因此它是属于故障这种分类。
另外我们需要注意的是一条指令在执行的过程当中有可能会产生多次缺页中断,因为一条指令当中可能会访问多个内存单元,比如说把逻辑地址、a 当中的数据,复制到逻辑地址 b 当中,如果说这两个逻辑地址属于不同的页面,并且这两个页面都没有调入内存的话,那么在执行这条指令的时候就有可能会产生两次中断。
通过之前的讲解我们会发现引入了缺页中断机构之后,系统才能实现请求调页这样的事情。
# 地址变换
接下来我们再来看一下,请求分页存储管理与基本分页存储管理相比,在地址变换的时候需要再多做一些什么事情。
- 第一个事情在查找到页面对应的页表项的时候,一定是需要对这个页面是否在内存这个状态进行一个判断。
- 第二个事情,在地址变换的过程当中,如果说我们发现此时选要访问的页面暂时没有掉入内存,但是此时内存当中又没有空闲的内存块的时候,那么在这个地址变换的过程当中,也需要进行页面置换的工作,换出某一些页面来腾出内存空间
- 第三个与基本分页存储管理不同的,就是当页面调入或者调出或者页面被访问的时候,需要对与它对应的这些页表项进行一个数据的修改。
所以我们在理解和记忆请求分页存储管理当中,地址变换过程的时候,需要重点关注这三件事情需要在什么时候进行,与基本分页存储管理相同,请求分页存储管理在逻辑地址变换为物理地址的过程当中需要做的第一件事情同样是要检查页号的合法性,看一下页号是否越界,如果页浩没有越界的话,就会查询此时在快表当中有没有页号对应的页表项,如果快表命中就可以直接得到最终的物理地址,如果快表没有命中的话,就需要查询内存当中的慢表。
在找到对应的页表项之后,需要检查此时这个页面是否已经在内存当中,如果说这个页面此时没有在内存当中的话,缺页中断机构会产生一个缺页中断的信号,之后就会有操作系统的缺页中断处理程序进行处理,包括调页还有页面置换那一系列的事情。当然当页面调入之后也需要修改页表相对应的一些数据。
这个地方注意一个细节,在请求分页管理方式当中,如果说能够在快表当中找到某一个页面对应的页表项,那么就说明这个页面此时肯定是在内存当中的。如果一个页面被换出了外存的话,那么快表项当中对应的这些页表项也应该被删除,所以只要快表命中,那么就可以直接根据内存块号,还有页内偏移量得到最终的物理地址了。这个页面肯定是在内存当中的
这个地方并没有像基本分页管理方式当中那样一步一步很仔细的分析,其实大家只需要关注请求分页管理方式与基本分页管理方式相比,不同的这些步骤就可以了。
其实课本当中给出了一个很完整的请求分页管理方式当中地址变换的流程图,大家需要重点关注的是这两个红框部分当中的内容,这些内容就是请求分页管理方式与基本分页管理方式相比,增加的一些步骤和内容。
根据这个图补充几个大家可能注意不到的细节,
- 第一个地方通过这个图,特别是 ① 这个步骤,大家有可能会发现只似乎只要访问了某一个页面,那么这个页面相关的修改位是不是就需要修改,其实并不是只有执行写指令的时候才会改变这个页面的内容。如果说执行的是读指令,那么其实不需要修改这个页面对应的修改位,并且一般来说在访问了某一个页面之后,只需要把这个页面在块表当中对应的表项的那些数据修改了就可以了,只有它所对应的那些表项要从快表当中删除的时候,才需要把这些数据从快表再复制回慢表当中,采取这样的策略的话,就可以减少访问内存当中慢表的次数,可以提升系统的性能。
- 第二个需要注意的地方是在产生了缺页中断之后,缺页中断处理程序也会保存 CPU 现场,这个地方其实和普通的中断处理是一样的,在中断处理的时候需要保存 CPU 的现场,然后让进程暂时进入阻塞,只有进程在重新回处理机运行的时候,才需要在恢复他的 CPU 现场。
- 第三个需要注意的地方是内存满的时候需要选择一个页面换出,到底换出哪个页面,这是页面置换算法要解决的问题,也是咱们下个小节当中会详细介绍的内容。
- 第四个需要注意的点是,如果我们要把页面写回外存,或者要把页面从外存调入内存的话,那么需要启动 lO 硬件,所以其实把页面换入换出的工作都是需要进行慢速的 lO 操作的。因此如果换入换出操作太频繁的话,系统会有很多的时间是在等待慢速的 l 操作完成的,因此页面的换入换出不应该太频繁。
- 第五个需要注意的地方,当我们把一个页面从外存调入内存之后,需要修改内存当中的页表,但是其实我们同时也需要把页表项复制到块表当中,所以由于新调入的页面在快表当中是有对应的页表项的,因此在访问一个逻辑地址的时候,如果发生了缺页,那么地址变换的步骤应该是这样的。第一步首先是查询快表,如果快表没有命中的话,才会查询内存当中的慢表,然后通过慢表会发现此时页面并没有掉入,内存当中之后系统会进行调页相关的操作,在页面掉入之后,不仅要修改内存当中的慢表,也需要把页表项同时加入到块表当中,于是之后可以直接从快表当中得到这个页面存放的位置,而不需要再查询慢表。
这是地址变换过程当中大家需要注意的几个点,其他的流程其实并不难理解,右半部分的这些流程其实和基本分页存储管理方式进行地址变换的这个过程是大同小异的,只不过是增加了修改页表项相应的内容这样一个步骤,
然后左半部分是新增的一系列处理,那要做的无非也就两件事,第一件事就是当我们发现所要访问的页面没有在内存当中的时候,需要把页面从外存调入内存,如果说内存此时已经满了,需要做页面置换的工作,当调页还有页面置换这些工作完成之后,也需要对页表还有块表当中的对应的一些数据进行修改。所以其实只要理解了,我们应该在什么时候请求调页,又应该在什么时候进行页面置换,当吊页和页面置换完成之后,又需要对哪些数据结构进行修改,只要知道这三个事情,那就可以掌握请求分页管理方式地址变换的这些精髓了。
# 小结
这个小节我们介绍请求分页管理方式与基本分页管理方式相比,请求分页管理方式在页表当中增加了状态位,访问字段、修改位,还有外存地址这样几个数据。大家需要理解这几个数据分别有什么作用。
之后我们介绍了缺页中断机构,在引入了缺页中断机构之后,如果一个页面暂时没有掉入内存,那就会产生一个缺页中断信号,然后之后系统会对缺页中断进行一系列的处理。另外大家需要注意的是缺页中断它是属于内中断,它和当前执行的指令有关,并且一条指令在执行的过程当中有可能会访问到多个内存单元,而这些内存单元有可能是在不同的页面当中的,因此一条指令执行的过程当中有可能会产生多次缺页中断。
最后我们介绍了请求分页管理方式的地址变换机构,其实我们只需要重点关注与基本分页方式不同的那些地方。第一,在找到页表项的时候,需要检查页面是否在内存当中,由此来判断此时是不是需要请求调页。在吊页的过程当中,如果发现此时内存当中已经没有空闲快,我们还需要进行换出页面的操作。另外在调入和换出了一些页面之后,我们也需要修改与这些页面对应的那些页表项,除了这些步骤以外,其他的其实和基本分页存储管理当中地址变换的过程并没有太大的区别。这个小节的内容在于理解不需要死记硬背,大家还需要通过,课后习题进行进一步的巩固和理解。
- 01
- 中国网络防火长城简史 转载10-12
- 03
- 公告:博客近期 RSS 相关问题10-02