《现代操作系统》– 存储管理、虚拟地址转换、淘汰换页算法

1.有两种处理内存超载的通用方法。最简单的策略是交换技术,即把一个进程完整调入内存,使该进程运行一段时间,然后把它存回磁盘。空闲进程主要存储在磁盘上,所以当他们不运行时就不会占用内存(尽管他们的一些进程会周期性地被唤醒以完成相关工作,然后又进入睡眠状态)。另一种策略是虚拟内存,该策略甚至能使程序在只有一部分被调入内存的情况下运行。

 

2.地址重定位:把程序地址空间的逻辑地址转换为存储空间的物理地址的工作叫地址重定位。又叫地址映射,或地址变换。

地址重定位的原因:
地址空间的逻辑地址往往与分配到的存储空间的物理地址不一致,
而处理机执行用户程序时,所要访问的指令和数据地址必须是实际的物理地址。

 

2.空闲内存管理:一般而言,有两种方式跟踪内存使用情况:位图和空闲链表。

①:使用位图的存储管理:使用位图方法时,内存可能被划分成小到几个字或大到几千字节的分配单元。每个分配单元对应于位图中的一位,0表示空闲,1表示占用(或者相反)。

②:使用链表的存储管理:维护一个记录已分配内存段和空闲内存段的链表。链表中的每一个结点都包含以下域:空闲区(H)或进程(P)的指示标志、起始地址、长度和指向下一结点的指针。

 

3.常用的空闲区链的管理的三种分配算法:

首次适应(first fit)法:要求空闲区按地址递增的次序排列。当进行内存分配时,从起始地址最小的空闲区开始扫描,直到找到一个能满足其大小要求的空闲区为止。分一块给请求者,余下部分仍留在空闲链中。

特点:优先利用低地址部分的空闲区,保留了高地址部分的大空闲区。
低地址端可能留下许多很少的空闲区,而每次查找是从低地址部分开始,会增加查找开销。

下次匹配法(next-fit):按分区的先后次序,从上次分配的分区起查找(到最后分区时再回到开头),找到符合要求的第一个分区。
特点:该算法的分配和释放的时间性能较好,使空闲分区分布得更均匀,但较大的空闲分区不易保留。

最佳适应(best fit)法:存储分配程序要扫描所有空闲区,以获得能满足进程需求且为最小的空闲区。
特点:因为分配分区要查找整个链表,所以比首次适应算法效率低。因为它可能把主存划分得更小,成为无用的碎片,所以它比首次适应要浪费更多的空贮空间。

最坏适应(worst fit)法:分配存储空间时,要扫描整个空闲区表,直到找到能满足进程要求且为最大的空闲区为止。然后,一分为二,一部分给进程,另一部分仍留在表中。
缺点:由于最大的空闲区总是首先被分配而进行划分,当有大作业到来时,其存储空间的申请往往得不到满足。

 

4.虚拟内存的基本思想:每个程序拥有自己的地址空间,这个空间被分隔成多个块,每一块称作一页或页面。每一页有连续的地址范围。这些页被映射到屋里内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立即执行必要的映射。当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令。

 

5.分页:我们程序产生的如:MOV REG,1000这些地址称为虚拟地址,它们构成了一个虚拟地址空间。在没有虚拟内存的计算机上,系统直接将虚拟地址送到内存总线上,读写操作使用具有同样地址的物理内存字;而在使用虚拟内存的情况下,虚拟地址不是被直接送到内存总线上,而是被送到内存管理单元,MMU把虚拟地址映射为物理内存地址。

图一

图二

当程序试图访问地址0时,比如使用这条指令:

MOV   REG,0

虚地址0将被送往MMU。MMU看到虚地址落在页0范围内(0到4095),根据它的映射这个页对应的是页框2(8192到12287),因此MMU把地址变换为8192并把地址8192送到总线上。内存板对MMU一无所知,它只看到一个对地址8192读或写的请求并且执行它。MMU从而有效地把所有从0到4095的虚地址映射到了8192到12287的物理地址。

如果MMU注意到这个页没有映射,于是使CPU陷入操作系统,这个陷入称为缺页。操作系统找到一个很少使用的页框并把它的内容写入磁盘,随后把需引用的页取到刚才释放的页框中,修改映射;然后重新启动引起陷入的指令。

 

6.MMU的内部结构以了解它是怎么工作的,以及为什么我们选用的页面大小是2的次幂。在图中我们可以看到一个虚地址的例子,虚地址8196(二进制是0010000000000100)用图示的MMU的映射进行映射,输入的16位虚地址被分为4位的页号和12位的偏移量,4位的页号可以表示16个页面,12位的位移可以为一页内的全部4096个字节编址。

页号可用作页表的索引,以得出对应于这个虚页的页框号。如果在/不在(Prsent/absent)位是0,则将引发一个操作系统的陷入;如果这个位是1,在页表中查到的页框号将被复制到输出奇存器的高三位中,加上输入虚地址中的12位偏移,就构成了15位的物理地址。输出 寄存器的内容随即被作为物理地址送到内存总线。

 

7.虚拟地址到物理地址的映射可以概括如下:

虚地址被分成虚页号(高位)和偏移(低位)两部分,虚页号被用做页表的索引以找到该虚页对应的页表项,从页表项中可以找到页框号(如果有的话)。随后页框号被拼接到偏移的高位端,形成送往内存的物理地址。页表的目的是把虚页映射为页框。从数学角度而言,页表是一个函数,它的参数是虚页号,结果是物理页框号。通过这个函数可以把虚地址中的虚页域替换成页框域,从而形成物理地址。

 

8.表项:表项的结构是与机器密切相关的,但不同机器的表项存储的信息大致相似。在图3-14中我们给出了页表项的样本,不同计算机页表项的大小不一样,但32位是一个一般的尺寸。最重要的域是页框号,毕竟页映射的目的是找到这个值;其次是在/不在位,这一位是1时这个表项是有效的可以被使用,如果是0,表示这个表项对应的虚页现在不在内存中,访问这一位为0的页会引起一个页面故障(缺页)。

 

9.多级页表:为了避免把庞大的页表始终保存在内存中,许多计算机使用了多级页表

32位的虚地址划分为10位(210)的PT1域、10位(210)的PT2域和12位(212)的偏移。因为偏移是12位,所以页长是(212=)4K,页面共有220个。

举一个例子,虚地址0x00403004(十进制4,206,596)位于数据部分(222-4206596=)12,292字节处。它对应的PT1=1、PT2=3、偏移(12292-3*212)=4。MMU首先用PT1作为索引访问顶级页表得到表项1,它对应的地址范围是4M到8M;随后它用PT2作为索引访问刚刚找到的二级页表并得到表项3,它对应的地址范围是在它的4M块内的12288到16383(即绝对地址4,206,592到4,210,687)。这个表项含有虚地址0x00403004所在页的页框号。如果这个页不在内存中,在/不在位将是0,一个页面故障将被引发;如果这个页在内存中,从二级页表中得到的页框号将和偏移(4)结合构成物理地址并通过总线送到存储器。

 

10.请求淘汰换页算法:

①:最优页面置换算法:置换将来使用次数少的页面。

②:最近未使用页面置换算法:利用在页表中设置一个访问位即可实现,当某页被访问时,访问位置“1”,否则访问位置“0”当需要淘汰一页时,从那些访问位为“0”的页中选一页进行淘汰。系统周期性地对所有访问位清零。

③:先进先出页面置换算法: 先进入内存的页面先淘汰。实现是在页表中登记进入的次序,并将各个已分配的页面按分配时间顺序连接起来,组成FIFO队列。优点是实现简单,缺点是遇到常用的页效率低下,并可能产生Belady现象(所谓Belady现象是指分配的页面数增多,缺页次数反而增加的现象)。

④:第二次机会页面置换算法:为了避免FIFO可能会把经常使用的页替换出去的问题,我们可以对它做一个简单的修改,对最老页面的R位进行检查。如果R位是0,那么这个页既老又没用,应该被立刻替换掉;如果是1,就清除这个位,把这个页放到页链表的尾端,修改它的装入时间让它就保刚装入的一样,然后继续搜索。

⑤:时钟页面置换算法:

尽管第二次机会算法是一个较合理的算法,但它经常要在链表中移动页面。既降低了效率,又是不必要的。一个更好的办法是把所有的页面保存在一个类似钟表面的环形链表中,如图示,有一个表针指向最老的页面。

  在发生页面故障时,算法首先检查表针指向的页面,如果它的R位是0就淘汰掉这个页,并把新页插入这个位置,然后把表针前移一个位置;如果R位是1就清除R位并把表针前移一个位置,重复这个过程直到找到一个R位为0的页为止。了解了这个算法的工作方式我们就不奇怪为什么它被叫做时钟了,它和第二次机会算法的区别仅仅是实现不同。

 

⑥:最近最少使用页面置换算法:当要淘汰某页时,选择离当时时间最近的一段时间内最久没有使用过的页面先淘汰。该算法的出发点是,如果某页被访问了,则可能它马上还要被访问,或者反过来说,如果某页面很长时间未被访问,则它在最近一段时间也不会被访问。LRU的实现是一件十分困难的事情,我们一般采用它的近似算法。

 

11.FIFO算法和LRU算法:

12.缺页中断处理

缺页中断处理发生的时间顺序:

①:硬件陷入内核,在堆栈中保存程序计数器。大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。

②:启动一个汇编代码例程保存通用寄存器和其他易失的信息,以免被操作系统破坏。这个例程将操作系统作为一个函数来调用。

③:当操作系统发现一个缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这一信息,如果没有的话,操作系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在做什么。

④:一旦中断了发生缺页中断的虚拟地址,操作系统检查这个地址是否有效,并检查存取与保护是否一致。如果不一致,向进程发出一个信号或杀掉该进程。如果地址有效且没有保护错误发生,系统则检查是否有空闲页框。如果没有空闲页框,执行页面置换算法寻找一个页面来淘汰。

⑤:如果选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其他进程运行直至磁盘传输结束。无论如何,该页框被标记为忙,以免因为其他原因而被其他进程占用。

⑥:一旦页框“干净”后(无论是立刻还是在写回磁盘后),操作系统查找所需页面在磁盘上的地址通过磁盘操作将其装入。该页面被装入后,产生缺页中断的进程仍被挂起,并且如果有其他可运行的用户进程,则选择另一个用户进程运行。

⑦:当磁盘中断发生时,表明该项已经被装入,页表已经更新可以反映他的位置,页框也被标记为正常状态。

⑧:恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。

⑨:调度引发缺页中断的进程,操作系统返回调用它的汇编语言例程。

⑩:该例程恢复寄存器和其他状态信息,返回到用户空间继续执行,就好像缺页中断没有发生过一样。

 

13.分页与分段比较:

转载请标注来源:www.blogfshare.com By:AloneMonkey

本文链接:http://www.alonemonkey.com/operating-system-two.html

2条评论

    1. AloneMonkey

      thank you!

Comments are closed.