操做系统(六)—— 存储管理

1、存储管理概述

一、存储体系

         内存空间,是由存储单元组成的一组连续的地址空间,简称内存空间。内存空间通常分为两部分:一部分是系统区,用以存储操做系统常驻内存部分,用户不能占用这部分空间;另外一部分是用户区,分配给用户使用,用于装入并存储用户程序和数据,这部分的信息随时都在发生变化。算法

二、存储管理的任务

        存储管理实质上就是管理供用户使用的那部分空间。编程

(1) 内存的分配与回收

        ① 静态分配。程序要求的内存空间是在目标模块链接装入内存时肯定分配的,而且在程序运行过程当中不容许再申请附加内存空间,即分配工做是在程序运行前一次性完成的。布局

        ② 动态分配。程序要求的基本内存空间是在目标模块装入时肯定并分配的,可是在程序运行过程当中容许申请附加的内存空间,即分配工做能够在程序运行前及运行过程当中逐步完成。操作系统

(2) 存储共享

       是指两个或多个进程共用内存中的相同区域,这样不只可以使多道程序可以动态的共享内存,提升内存利用率,并且还能共享内存中某个区域的信息。共享的内容包括代码共享和数据共享,特别是代码共享要求代码必须是纯代码。设计

        存储共享的一个目的是经过代码共享节省内存空间,提升内存利用率;另外一个目的是经过数据共享实现进程通讯。指针

(3) 存储保护

        存储保护的内容包括:保护系统程序区不被用户有意或无心的侵犯;不容许用户程序读写不属于本身地址空间的数据,如系统区地址空间、其余用户程序的地址空间。队列

三、地址转换

(1) 地址重定位

        把逻辑地址转换成绝对地址的工做称为“地址重定位”或“地址转换”,也称“地址映射”。重定位的方式有“静态重定位”和“动态重定位”。进程

(2) 静态重定位

        内存在装入程序时,要把程序中的指令地址和数据地址所有转换成绝对地址。因为地址转换工做是在程序开始前集中完成的,因此在程序执行过程当中就无需再进行地址转换工做,这种地址转换方式称为静态重定位。事件

(3) 动态重定位

        内存在装入程序时,不进行地址转换,而是直接把程序装入到分配的内存区域中。在程序执行过程当中,每当执行一条指令时都由硬件的地址转换机构将指令中的逻辑地址转换成绝对地址。这种方式的地址转换是在程序执行时动态完成的,因此称为动态地址转换。内存

2、分区管理方案

一、固定分区

        固定分区是指系统先把内存划分红若干个大小固定的分区,一旦划分好,在系统运行期间便再也不从新划分。为了知足不一样程序的存储需求,各分区的大小能够不一样。因为每一分区的大小是固定的,就对可容纳程序的大小有所限制。所以,程序在运行时就必须提供对内存资源的最大申请量。

二、可变分区

        可变分区是指系统不预先划分固定分区,而是在装入程序时划份内存分区,使为程序分配的分区的大小正好等于该程序的需求量,且分区的个数是可变的。显然,可变分区有较大的灵活性,较之固定分区能得到较好的内存利用率。

        系统初启后,在内存中除操做系统区以外,其他空间为一个完整的大空闲区。当有程序要求装入内存运行时,系统从该空闲区中划分出一块大小相同的区域进行分配。当系统运行一段时间后,随着一系列的内存分配与回收。原来的一整块大空闲区造成了若干占用区和空闲区相间的布局。如有上下相邻的两块空闲区,系统应将它们合并成一块连续的大空闲区。

(1) 紧缩技术

        解决碎片问题的办法是在适当时刻进行碎片整理,经过移动内存中的程序,把全部空闲碎片合并成一个连续的大空闲区并放在内存的一端,而把全部程序占用区放在内存的另外一端。这一技术称为“紧缩技术”或“压缩技术”。

(2) 内存分配表

        内存分配表由两张表格组成。一个是已分配区表,记录已装入程序在内存中占用分区的起始地址和长度,用标志位指出占用分区的程序名。另外一个是空闲区表,记录内存中可供分配的空闲区的起始地址和长度,用标志位指出该分区是未分配的空闲区。

(3) 操做系统查找和分配空闲区的三种分配算法

① 最早适应算法

        又称为顺序分配算法,当接到内存申请时,顺序查找分区说明表,找到第一个知足申请长度的空闲区,将其分割并分配。此算法比较简单,能够快速做出分配决定。

② 最优适应算法

        当接到内存申请时,查找分区说明表,找到第一个能知足申请长度的最小空闲区,将其分割并分配。此算法最节约空间,由于它尽可能不分割大的空闲区;其缺点是可能会造成不少很小的空闲内存碎片。

③ 最坏适应算法

        当接到内存申请时,查找分区说明表,找到能知足申请要求的最大空闲区。该算法的基本思想是:在大空闲区中装入信息后,分割剩下的空闲区相对也很大,还能用于装入其余程序。

(4) 分区管理方案的优缺点

        分区管理是实现多道程序设计的一种简单易行的存储管理技术。经过分区管理,内存真正成为了共享资源,有效地利用了处理器和IO设备,从而提升了系统的吞吐量和缩短了周转时间。分区存储管理算法比较简单,所采用的表格很少,实现起来比较容易,内存额外开销较少,存储保护措施也很简单。

        在内存利用率方面,可变分区的内存利用率比固定分区高。

        分区管理的主要缺点是:内存使用仍不充分,而且存在着较为严重的碎片问题。虽然能够解决碎片问题,但须要移动大量信息,浪费了处理器的时间。此外,分区管理不能为用户提供虚拟存储,即不能实现对内存的扩充,每个用户程序的存储要求仍然受到物理存储器实际存储容量的限制。分区管理要求运行程序一次所有装入内存以后,才能开始运行。这样,内存中可能包含有一些实际不使用的信息。

3、覆盖与交换技术

一、覆盖技术

        覆盖技术是指一个程序的若干程序段,或几个程序的某些部分共享一个存储空间。覆盖技术的实现是把程序划分为若干个功能上相对独立的程序段,按照其自身的逻辑结构使那些不会同时执行的程序段共享同一块内存区域。未执行的程序段先保存在磁盘上,当有关程序段的前一部分执行结束后,把后续程序段调入内存,覆盖前面的程序段。

二、交换技术

        在分时系统中,用户的进程比内存能容纳的数量要多,这就须要在磁盘上保存那些内存中放不下的进程。在须要运行这些进程时,再将它们装入内存。

        在实际操做系统中使用交换技术须要考虑的问题:换出进程的选择、交换时机的肯定、交换空间的分配、换入进程换回内存时位置的肯定。

4、虚拟页式存储管理方案

一、虚拟存储技术

        虚拟存储技术的基本思想是利用大容量的外存来扩充内存,产生一个比实际内存大的多的逻辑虚拟内存空间,简称虚存,以便可以有效地支持多道程序系统的实现和大型程序运行的须要,从而加强系统的处理能力。

        虚拟存储器的工做原理:当进程开始运行时,先将一部分程序装入内存,另外一部分暂时留在外存;当要执行的指令不在内存时,由系统自动完成将它们从外存调入内存的工做;当没有足够的内存空间时,系统自动选择部份内存空间,将其中原有的内容交换到磁盘上,并释放这些内存空间供其余进程使用。

        虚拟存储技术和交换技术在原理上有些类似,不一样的是交换技术是以进程为单位进行的,而虚拟存储通常是以页为单位进行的。

二、虚拟页式存储管理

        存储管理部件首先将内存分红大小相等的许多区,把每一个区称为物理页面,物理页面是进行内存空间分配的物理单位。同时,要求程序中的逻辑地址也进行分页,页的大小与物理页面的大小一致。此时,逻辑地址可被称为虚拟地址。这样,就能够把程序信息按页存放到物理页面中。页式存储地址提供编程使用的虚拟地址由两部分组成:虚拟页号和页内地址。

三、物理内存的分配与回收

        页式存储管理分配内存空间以物理页面为单位,因为物理页面的大小是固定的,因此只要在内存分配表中指出哪些物理页面已经分配、哪些物理页面没有分配以及当前剩余空间的物理页面数这三种标识便可。

        简单的内存分配表能够用一张位示图构成,在位示图中每一位与一个物理页面对应,每一位的值能够是0或1,0表示对应的物理页面为空闲,1表示已占用。在位示图中再增长一个字节记录当前剩余的总空闲物理页面数,在进行内存分配时,首先查看空闲物理页面数是否能知足要求,能知足则从位示图中找出一些为0的,将值更新为1,并从空闲页面数中减去本次分配的页面数,而后按照找到的位计算出对应的物理页面号。

四、虚拟页式存储地址转换过程

        页式存储管理要为每一个装入内存的进程提供一张页表,该页表所在内存的起始地址和长度做为现场信息存储在该进程的进程控制块中。一旦进程被调度进入处理器执行,这些信息将被做为恢复现场信息送入系统的地址映射机制中的寄存器里。

(1) 页式存储管理的地址转换

       为了实现页式存储管理,系统要提供一对硬件的页表控制寄存器,即页表始址寄存器和页表长度寄存器,另外还须要高速缓冲存储器的支持。

        页表指出该程序虚拟地址中的页号与所占用的物理页面号之间的对应关系,页表的长度由程序拥有的页面数而定。

        页表又是硬件进行地址转换的依据,每执行一条指令时按虚拟地址中的页号来查询页表。若是表中无此页号,则产生一个地址错的程序性中断事件。如有,则能够获得对应的物理页面号。

(2) 页表项

        在进程开始运行以前,不是装入所有页面,而是装入零个或多个页面,以后根据进程运行的须要,动态装入其余页面;当内存空间已满,而又须要装入新的页面时,则根据某种算法淘汰某个页面,以便装入新的页面。

(3) 页表的分类

① 多级页表

        大多数操做系统中采用二级页表,即由页表页和页目录一块儿构成进程页表。第一级表示页目录,保存页表页的地址;第二级表示页表页,保存物理页面号。

② 散列页表

        当地址空间大于32位时,一种常见的方法是使用以页号为散列值的散列页表。其中每一个表项都包含一个链表,该链表中元素的散列值都指向同一个位置。这样,散列页表中的每一个表项都包含三个字段:虚拟页号、所映射的页框号、指向链表中的下一个元素的指针。

③ 反置页表

        在反置页表中,每一个物理页框对应一个表项。每一个表项包含与该页框对应的虚拟页面地址,以及拥有该页面进程的信息。所以,整个系统中只存在一个页表,而且每一个页框对应其中一个表项。因为一方面系统中只有一个页表,而另外一方面系统中又存在着多个映射着物理内存的地址空间,所以须要在反置页表中存放地址空间标志符。

(4) 转换检测缓冲区

        利用高速缓冲存储器存储当前访问最频繁的小数活动页面的页号,这个高速缓冲存储器称为“转换检测缓冲区”,也称为“快表”。

(5) 缺页异常处理

① 根据当前执行指令中的逻辑地址查页表的有效位,判断该页是否在内存中;

② 该页标志为0,造成缺页异常。保留现场,中断装置经过交换PSW让操做系统中的中断处理程序占用处理器;

③ 操做系统处理缺页异常,寻找一个空闲的页面;

④ 如有空闲页,则把磁盘上读出的信息装入该页面中;

⑤ 修改页表及内存分配表,表示该页已在内存;

⑥ 若是内存中没有空闲页,则按某种算法选择一个已在内存中的页面,把它暂时调出内存。若在执行中该页面已被修改过,则要把该页信息从新写回到磁盘上,不然没必要从新写回磁盘。当一页被暂时调出内存后,让出的内存空间用来存储当前须要使用的页面。页面被调出或装入以后都要对页表及内存分配表做修改。

⑦ 恢复现场,从新执行被中断的指令。当从新执行该指令时,因为要访问的页面已被装入内存,因此能够正常执行下去。

(6) 页面高度策略

        虚拟存储器系统一般定义三种策略来规定如何进行页面调度:调入策略(请求调页和预调页)、置页策略和置换策略(固定分配局部换、可变分配全局置换和可变分配局部置换)。

(7) 页面置换算法

① 理想页面置换算法(OPT)

        OPT算法淘汰之后再也不须要的或者在最长时间之后才会用到的页面。

② 先进先出页面转换算法(FIFO)

        FIFO算法老是选择最早装入内存的一页调出,或者说是把驻留在内存中时间最长的一页调出。

        FIFO算法的实现过程是:把装入内存的那些页面的页号按进入的前后次序排好队列,每次老是调出队首的页,当装入一个新页后,把新页的页号排入队尾。由操做系统维护一个全部当前在内存中的页面的链表,最老的页面在表头,最新的页面在表尾。当发生缺页时,淘汰表头的页面并把新调入的页面加入到表尾。

③ 第二次机会页面置换算法

        FIFO算法可能会把常用的页面置换出去,为了不这一问题,对该算法进行一个简单的修改:检查进入内存时间最久页面的R位,若是是0,那么这个页面既老又没有被使用,能够当即置换到;若是是1,就将R位清0,并把该页面放到链表的尾端,修改其进入时间,而后继续搜索。

④ 时钟页面转换算法

        因为第二次机会算法常常要在链表中移动页面,下降了效率,一个更好的办法是把全部的页面都保存在一个相似时钟钟面的环形链表中,一个表针指向最老的页面。当发生缺页时,算法首先检查表针指向的页面,若是它的R位是0就置换该页面,并把新的页面插入这个位置,而后把表针向前移动一个位置;若是R位是1就清除R位并把表指针向前移一个位置,重复这个过程直到找到了一个R位为0的页面为止。

⑤ 最近最少使用的页面置换算法(LRU)

        这个算法是淘汰掉最长时间未被使用过的页面。实现它的方法是:在页表中为每一页增长一个计时标志,记录该页面自上次被访问以来所经历的时间,每被访问一次都应从0开始从新计时。当要装入新页面时,检查页表中各页的计时标志,从中选出计时值最大的那一页调出,而且把各页的计时标志所有置为0,从新计时。

(8) 缺页率

        影响缺页率的因素有:

① 分配给程序的物理页面数;

② 页面的大小;

③ 程序编制方法;

④ 页面调度算法。

五、虚拟页式存储管理的优势和缺点

        虚拟页式存储管理的主要优势是:因为它不要求进程的程序段和数据在内存中连续存放,从而有效地解决了碎片问题。这既提升了内存利用率,又有利于组织多道程序执行。

        虚拟页式存储管理的主要缺点是:存在页面空间的浪费问题,这是因为各类程序代码的长度是各不相同的,但页面的大小是固定的,因此在每一个程序的最后一页内总有一部分空间得不到利用。若是页面较大,则由此引发的存储空间的损失仍然较大。