存储管理 - 操作系统概论

计算机系统中的存储器

       存储器分为:寄存器、主存储器和高速缓冲存储器、辅助存储器(磁带、软盘、硬盘、光盘等)三个层次。处理器能直接访问寄存器、主存储器和高速缓冲存储器,但不能直接访问辅助存储器。

  • 寄存器

       寄存器存取速度最快,但价格昂贵,因此容量很小。一般,每个寄存器只能存储一个字长的信息,故只用来存放临时的工作数据和控制信息。

       常用的寄存器有 3 类:

  1. 指令寄存器。存放当前从主存储器中读出的指令。
  2. 通用寄存器。存放参加运算的操作数、运算结果等。
  3. 控制寄存器。存放控制信息,保证程序的正确执行和系统安全。如程序状态字寄存器(存放 PSW)、基址寄存器、界限寄存器(限定程序执行时可访问的主存空间的范围)等。
  • 主存储器

       主存储器的存储量较大、存取速度也较快。存储单元以字节为单位进行编址。若干个字节组成一个字。处理器按地址 读/写 一个字节或一个字。

  • 高速缓冲存储器

       高速缓冲存储器存取速度快于主存储器,但造价要比主存储器高,因而存储容量不大。当主存储器中的某些信息经常被访问时,可复制到高速缓冲存储器中,以提高程序执行的速度。

  • 辅助存储器

       辅助存储器的存储容量很大,可用来长期存储信息。但从辅助存储器读写信息时必须启动相应的外设,因此存取速度较慢。

 

       从上述的简单介绍中可以看出,寄存器是用来存放控制信息或临时存放当前运行程序的工作数据。哪个进程占用处理器,这些寄存器就为哪个进程服务,故不存在寄存器的分配问题。

       由于操作系统必须占用主存储器的一部分存储空间,用来存放操作系统的程序、数据、管理信息(如 PSB)以及操作系统与硬件的接口信息(如新、旧 PSW)等,我们把这部分空间称为 系统区。除系统区外的其余主存空间可用来存放用户的程序和数据,称为 用户区

       存储管理 就是对主存储器中的用户区进行管理,包括主存空间的分配和回收、共享和保护、地址转换以及主存空间的扩充等工作。

 

重定位

  • 绝对地址和逻辑地址

       主存储器中的存储单元以字节为单位,每个存储单元都有一个地址与其对应(如 n 个存储单元的地址编号为 0 ~ n-1)。主存空间的地址编号称为主存储器的 绝对地址,与绝对地址对应的存储空间称为 物理地址空间

       采用多道程序设计技术后,往往在主存储器中同时存放多个用户作业,由于用户并不能预先知道自己的作业将被放到主存储器的什么位置,这样用户编写程序时就不能使用绝对地址。为方便用户,每个用户都可以认为自己作业的程序和数据存放在一组从 0 开始的连续空间中,用户程序中使用的地址称为 逻辑地址,与逻辑地址对应的存储空间称为 逻辑地址空间

  • 重定位

       处理器必须按照绝对地址去访问主存储器才能保证程序的正确运行,因此,必须把分配给用户作业的主存空间的地址进行重定位,即要把逻辑地址转换成绝对地址,这种转换的工作就称为 重定位 地址转换

       重定位有 2 种 方式:

  1. 在装入一个作业时,把作业中的指令地址和数据地址全部转换为绝对地址,这种转换工作是在作业执行前集中一次性完成的,所以在执行过程中就无需再进行地址转换工作,这种定位方式称为 静态重定位
  2. 动态重定位由软件和硬件相互配合来实现。硬件设置一个基址寄存器,当存储管理为作业分配了一个主存区域后,把该主存区域的起始地址存入基址寄存器中,在执行指令时只要把逻辑地址与基址寄存器中的值相加就可以得到绝对地址。由于这种方式是在指令的执行过程中进行的,所以称为 动态重定位

        采用静态重定位时,由于装入主存储器中的作业信息已经全部使用了绝对地址,故作业在执行中不能移动位置。采用动态重定位时,由于装入主存的作业仍保持原来的逻辑地址,所以可以改变它在主存空间的区域,只需将新区域的起始地址存入基址寄存器中即可。

 

单用户连续存储管理

       这是最简单的存储管理方式。操作系统占了一部分主存空间,再给一个用户作业分配主存空间,任何时刻仅有一个用户作业在主存储器中,故适合单道运行的计算机系统。采用这种方式时,处理器中设置一个界限寄存器,存放当前可供用户作业使用的主存区域的起始地址。

       由于单用户连续存储管理每次只允许一个作业进入主存储器中,因此不必考虑作业在主存储器中的移动问题,可采用静态重定位方式,硬件也不必有地址转换机构。但处理器在执行指令时要检查其绝对地址是否 >= 界限地址,且 <= 最大地址,若在规定范围内,则可执行,否则产生一个“地址越界”中断事件,由操作系统进行处理,已达到存储保护的目的。

 

固定分区存储管理

       固定分区存储管理 是把主存储器中可分配的用户区域预先划分成若干个连续区,每一个连续区称为一个 分区。一旦划分后,分区的个数就固定了。各个分区的大小可以相同,也可也不同,但每个分区的大小固定不变。这种管理方式适用于多道程序设计系统。

  • 主存空间的分配与回收

       存储管理中设置了一张“分区分配表”用来说明各分区的分配和使用情况。表中指出各分区的起始地址和长度,并为每个分区设置一个标志位(0 - 空闲,非 0 - 被占用)。分区分配表的长度等于分区的个数。

  • 地址转换和存储保护

       由于固定分区管理方式是预先把主存分成若干分区,每个区只能装入一个作业,因此作业在执行过程中是不会被改变存放区域的,于是可采用静态重定位的方式把作业装入到所分配的分区中。

       为了实现存储保护,处理器设置了一对寄存器,称为“下限寄存器”和“上限寄存器”。当一个已被装入主存储器中的作业得到处理器运行时,进程调度应记录当前运行作业所在的分区号,且把该分区的“下限地址”和“上限地址”存入这对寄存器中。为防止破坏其他分区中的信息,处理器执行指令时必须核对绝对地址是否越界,如果越界了,硬件产生“地址越界”中断事件,以达到存储保护的目的。

  • 如何提高主存空间的利用率

       使用固定分区方式管理主存储器时,总是为作业分配一个不小于作业长度的分区,因此许多作业实际上只占用了分区的一部分,使分区中有一部分区域闲置不用,降低了主存空间的利用率。

       为了提高主存空间的利用率,可采用下列几种措施:

  1. 根据经常出现的作业的大小和数量来划分分区,尽可能使各分区被充分利用。
  2. 划分分区时,使分区大小不均,由小到大依次排列,并记录在分区分配表中。于是只要顺序查找该表就可方便的找出一个能满足作业要求的最小空闲分区分配给作业。即使闲置的空间尽可能减少,又尽量保留较大的空闲空间以利于大作业的装入。
  3. 将多个作业先以对存储空间的需求量进行分组,形成多个作业队列。例如,队列1 中各个作业只能进入分区1,每次装入一个作业。队列2 的各个作业只能进入分区2,每次装入一个作业。某个作业队列为空时,对应的分区就保持空闲,直到该队列有作业时再被使用。采用多个作业队列的固定分区方式能有效防止小作业进入大分区,从而减少闲置的主存空间。

 

可变分区存储管理

       可变分区存储管理  是在作业要求装入存储器时,根据作业需要的主存空间大小和当时主存空间的使用情况来决定是否为作业分配一个分区。因此分区的长度不是预先固定的,分区的个数也不是预先确定的。即来一个作业,就从主存储器的空闲区域中分配一个符合作业需求量的空间,因此能克服固定分区方式中分区空间不能被充分利用的缺陷。

  • 主存空间的分配与回收

       采用可变分区存储管理时,主存储器中空闲区的数目和大小是不断变化的。为了便于管理,必须设置一张“空闲区表”来记录空闲区的起始地址和长度。

       当有作业进入主存储器后时,在空闲区表中查找状态为“未分配”的分区,进行下面 2 种情况的分配:

  1. 空闲分区 > 作业长度,则给作业按需分配,剩余部分仍作为空闲区并登记在表中。
  2. 空闲分区 = 作业长度,正好全部分给作业,并在表中登记该栏的状态为“空”。

       当有作业执行结束时,收回作业所占用的主存空间,把收回区域的起始地址和长度登记在状态为“空”的栏目中。

       可变分区存储管理常用的主存分配算法有:

  1. 最先适应分配算法。顺序查找空闲区表,找到能满足作业长度的第一个空闲区,分割这块区域,一部分分配给作业,另一部分仍未空闲区。这种分配算法实现简单,但经多次分配后,会把大的主存空间分割成许多小的、不连续的空闲区,我们把这些不连续的空闲区称为 碎片。碎片过多会使主存空间的利用率降低。
  2. 最优适应分配算法。按作业长度从所有空闲区中挑选一个能符合作业的最小空闲区,这可以保证不去分割更大的区域,使大作业比较容易得到满足。实现这种算法时,可把空闲区按长度以递增的次序登记在空闲区表中,在分配时就很容易查找到最小的又符合作业要求的空闲区,回收空闲区时空闲区表再按长度递增的顺序排序,并把这个空闲区插入登记到表中的适当位置。采用这种算法,有时找到的分区可能只比作业大一点点,这样经过多次分割后,剩下的空闲区就极小了,往往无法使用,也会降低主存空间的利用率。
  3. 最坏适应分配算法。总是挑选一个最大的分区分割一部分给作业使用,使剩下的部分不至于太小,仍可供下次分配使用。实现这种算法时,空闲区表中的登记项可按长度递减排序,于是先找到的分区总是最大的,回收时再此将空闲区表按长度递减的顺序排序,在适当的位置插入回收的空闲区。

       无论在哪一种可变分区存储管理的方式下,收回主存空间时都应检查是否有与收回区相邻的空闲区,若有,则应合并成一个空闲区再登记入表中。

  • 地址转换与存储保护

       采用可变分区方式管理时,一般均采用动态重定位的方式装入作业,因此,需要有硬件的地址转换机制作支持。硬件设置两个专用的控制寄存器:基址寄存器和限长寄存器,以及一些加法线路,比较线路等。

       当作业占用处理器执行时,进程调度把作业所占分区的起始地址送入基址寄存器,把作业所在分区的最大地址送入限长寄存器。处理器每执行一条指令,就要由硬件的地址转换机制把逻辑地址转换成绝对地址(基址 + 逻辑地址),并判断地址是否越界(基址寄存器 <= 绝对地址 <= 限长寄存器),以达到存储保护的目的。

       基址寄存器和限长寄存器总是存放当前占用处理器的作业所占分区的起始地址和末尾地址

  • 移动技术

       可变分区方式的存储管理采用动态重定位方式装入作业,因而对已经在主存储器中的作业可根据需要改变存放位置。把作业从一个存储区域移动到另一个存储区域的工作称为 移动

       采用移动技术的目的主要有 2 个:

  1. 集中分散的空闲区。当主存储器中各个空闲区的长度都不能满足作业,而这些空闲区长度之和又可以满足作业时,则可移动在主存储器中的作业,使各分散空闲区连成一片形成一个大的空闲区,从而将作业装入,使主存空间充分被利用。
  2. 便于作业动态扩充主存。作业在执行中要求增加主存量时,只需适当移动临近作业就可增加它所占的连续区域。

       采用移动技术的注意事项

  1. 移动会增加系统开销。我们把操作系统所占用的系统资源和所需的处理器时间称为 系统开销。移动作业时需要做信息的传送工作,并且作业被移动后使得所占用的分区以及空闲区的位置和长度均发生了变化,因而必须修改相应的进程控制块中所保存的所占分区的始址,修改空闲区表等信息。这些都将增加操作系统占用处理器的时间,使系统开销增大。
  2. 移动是有条件的。因为外围设备与主存储器之间的信息交换是按确定了的主存绝对地址进行传送的。如果这时改变了作业的存放区域,则改作业就得不到外围设备传送来的信息,或不能把信息正确的传送到外围设备。所以在移动作业时,应先判定它是否在与外围设备交换信息。

       在采用移动技术的系统中,应尽可能减少移动,以降低系统开销,提高系统效率。

 

页面虚拟存储管理

       前面介绍的几种存储管理方式,要求作业的逻辑地址空间连续的存放在主存储器的某个区域中,当主存储器没有足够大的空闲区时,作业无法装入,或者必须移动某些作业后才能装入。

       采用页面虚拟存储管理,可实现在较小的主存空间里运行较大的作业,既可充分利用主存空间又可减少移动所增加的系统开销。

  • 页式存储管理的基本原理

       页式存储管理  是把主存储器分成大小相等的许多区,每个区称为一块。与此对应,程序的逻辑地址也分成页,页的大小与块的大小相等。

       分页式存储器的逻辑地址由两部分组成:页号 + 页内地址。地址结构确定了主存储器的分块的多少,也决定了页面的大小。假定其长度为 15 位,例如:001110000000011(00111 - 页号,0000000011 - 页内地址)。页号占了 5 位,页内地址占了 10 位。即逻辑地址可有 32 页,页号:0 ~ 31,每一页有 1024 个字节:0 ~ 1023。这样,一组顺序的连续地址自然的由地址结构被分页了。

       总是以块进行分配,一个作业的信息有多少页,进入主存时就给它分配多少块,但这些块可以是不连续的,采用见缝插针的方法,主存中哪一块空闲,就被用来存放作业的一页。

  • 页式存储空间的分配和回收

       可用一张贮存分配表来记录已分配的块和尚未分配的块以及当前剩余的空闲块数。假设主存储器的可分配区域被分成 256 块,则可用字长 32 位的 8 个字的位示图来构成贮存分配表,用 0/1 表示 空闲/占用,再用一个字节记录当前剩余的空闲块数。如下图:

       存储管理 - 操作系统概论_第1张图片

       进行主存分配时,先查空闲块数能否满足作业要求,若能满足,则找出为 “0”的一些位,并置为“1”,从空闲块数中减去本次占用块数。根据为“0”的位所在的字号和位号,可计算出对应的块号:块号 = 字号 * 字长 + 位号;例如(3 * 32 + 2 = 98,块号为 98)。

       当一个作业结束并收回所占主存时,根据归还的块号计算出位示图中对应的位置,将占用标志改为“0”,再把归还块数加到空闲块数中。从块号计算出对应的位置:字号 = 块号 / 字长(取整),位号 = 块号 mod 字长(求余数),例如,98 / 32 = 3(字号),99 % 32 = 2(位号)。

  • 页表和地址转换

       当主存中空闲块数能满足作业要求时,存储管理就找出这些空闲块分配给作业,同时为作业建立一张页表,指出逻辑地址中页号与主存中块号的映射关系。一张占用 4 页的作业,页表格式如下:

页号 块号
0 10
1 12
2 13
3 16

       页式存储管理采用动态重定位的方式装入作业,作业执行时由硬件的地址转换机构来完成从逻辑地址到绝对地址的转换。处理器每执行一条指令,地址转换机构就按逻辑地址中的页号查询页表得到对应主存的块号,再按逻辑地址中的页内地址换算出欲访问的主存单元的绝对地址。由于块的长度都是相等的,所以地址转换公式为:绝对地址 = 块号 * 块长 + 页内地址。

       实际上,由于分块和分页的大小是一致的,再利用二进制乘法的特性,只要把逻辑地址中的页内地址作为绝对地址的低位,把根据页号查询页表得到的块号作为绝对地址的高位,就能得到主存储器的绝对地址!如图:

       存储管理 - 操作系统概论_第2张图片

       因此,虽然作业被存放在若干个不连续的块中,但在执行时总能按确切的绝对地址进行存取,保证了作业的正确执行。

       但是,页式存储管理中的页表是放在主存储器中的,当按给定的逻辑地址进行读写时,就需要访问 2 次主存。(先查页表得到块号,再按算出的绝对地址进行读写),这就延长了指令的执行周期,降低了执行速度。为了提高存取速度,通常设置一个小容量的高速缓冲存储器。利用高速缓冲存储器存放页表的一部分,把存放在高速缓冲存储器中的部分页表称为 快表

       根据程序执行局部特性的特点,在一段时间内总是经常访问某些页,若把这些页登记在快表中,则可快速查找并提高执行速度。

       有了快表后,地址转换的过程:

  1. 根据逻辑地址中的页号同时查快表和页表
  2. a. 若快表有,则拿查到的块号与逻辑地址中的页内地址合成绝对地址,同时停止查页表的工作。b. 若快表无,则拿页表中的块号与页内地址合成绝对地址,同时将该页登记入快表。

       另外,由于快表容量较小,被填满后再登记新页时,就必须淘汰快表中的一个旧登记项。最简单的策略是“先进先出”。

       采用快表后,地址转换时间大大下降。假定访问主存的时间为 200 豪微秒,访问高速缓冲存储器的时间为 40 豪微秒,假设查快表的命中率可达 90%,于是逻辑地址转换为绝对地址再进行存取的平均时间为:(200 + 40)* 90% + (200 + 200)* 10% = 256 豪微秒;不使用快表时为 400 豪微秒;前者减少了 144 豪微秒,所需时间下降了 144 / 400 = 36%。

  • 页的共享和保护

       页式存储管理有利于实现多个作业共享程序和数据。在多道程序设计系统中,编译程序、编辑程序、解释程序、公共子程序、公共数据等都是可共享的。这些共享的信息在主存储器中只要保留一个副本,各作业共享这些信息时,可使它们各自页表中有关表目指向共享信息所在的主存块。

       页的共享可节省主存空间,但实现信息共享必须解决共享信息的保护问题。通常的办法是在页表中增加一些标志,指出该页的信息可 读/写、只读、可执行。

  • 什么是虚拟存储器

       在前面介绍的各种存储管理方式中,必须为作业分配足够的存储空间,以装入作业的全部信息。但在程序的运行中,程序有些部分是互斥的,执行了这部分就不会执行那一部分,例如错误处理只有在程序出错时才会执行;另外,程序执行有局部性,例如某些时刻可能会循环执行某些指令或多次访问某一部分的数据。于是,就提出了这样的问题:能否不把作业的全部信息同时装入主存储器,而是先装入一部分,另一部分暂时存在磁盘上,作业执行时用到那些不再主存储器中的信息时,再把它们装入主存储器中?

       如果这个问题能够解决,当主存空间小于作业需求量时,作业也能执行,这就使得主存空间能被充分利用,进而用户编制程序时可以不必考虑主存储器的实际容量,允许用户的逻辑地址大于主存储器中的绝对地址,对用户来说就好像计算机系统有一个容量很大的存储器,称为 虚拟存储器

       虚拟存储器的容量由计算机的地址结构和辅助存储器(如磁盘)的容量决定,与实际存储器的容量无关,是为扩大主存容量而采用的一种管理技巧。

       实现虚拟存储管理必须解决 3 个关键问题:

  1. 怎样知道哪些信息已在存储器中,哪些信息尚未装入?
  2. 作业要访问没有装入主存储器中的信息时,怎样装入?
  3. 把欲访问的信息装入主存储器时,发现主存空间不够时该怎么办?
  • 页式虚拟存储管理的实现

       1. 实现原理

       对采用页式管理的存储器来说,能很方便的改造成虚拟存储器。改造方法很简单,只需将作业的全部信息作为副本存放在磁盘上,作业调度选中一个作业时,至少把作业的第一页信息装入主存中,在作业执行过程中欲访问不再主存储器中的页时,再把它们装入。

       为此需要对页表进行改造,首先在页表中指出哪些页已在主存储器中,哪些页还没有装入,并且指出每一页副本在磁盘上的位置。例如:

页号

标志

主存块号

磁盘上的位置

0

1(已装入主存)

10

 

1

0(未装入主存)

 

1086

 

   

       然后,在作业执行中访问某页时,由硬件的地址转换机构查询页表,若标志为“1”,则按指定的主存块号进行地址转换,得到绝对地址。若标志为“0”,则由硬件发出一个“缺页中断”,操作系统必须处理这个中断事件。处理器检查主存空间是否有空闲块,若有,则从磁盘上读取该页装入主存储器,并在页表标记该页所占主存块号,修改标志位,再重新执行被中断的指令就可找到要访问的主存单元。

       2. 页面调度

       欲装入某页时,若主存储器中已没有空闲块,则必须先调出已在存储器中的某一页,再将当前所需的页调入,同时对页表作相应的修改。选择某种算法选择一页暂时调出,把它存放到磁盘上,让出主存空间,用来存放当前要使用的页,这一过程称为 页面调度

       页面调度算法的选择很重要,如果选用了一个不合适的调度算法就会出现这样的现象:刚被调出的页立即又要使用,因而又要把它调入;而调入不久又被调出;调出不久又被调入。如此反复,使调度非常频繁,以至于大部分时间花在来回调度上,这种现象称为 抖动,又称 颠簸

       应选择一种好的调度算法,减少和避免抖动现象。常用的页面调度算法有:

  1. 先进先出调度算法(First in First out,FIFO)。实现很简单,装入的页按进入先后排成队列,用一个指针 K 始终指向要被调出的页,刚开始指向队首位置,当有新页进入,在指针所处位置填上新页页号,然后指针 K + 1,指向下一个应淘汰的页。注意,这里的 K 是循环指针,假定队列里有 n 个页号,那么每次调出一页后,K = (k + 1) mod n 。这种算法始终调出在存储器中呆的最久的页,而不考虑该页的使用频率。
  2. 最近最久未使用调度算法(Least Recently Used,LRU)。这种算法认为,经常被使用到的页很可能马上还要被访问,因此不能把它调出,相反,在最近一段时间里最久没有被访问的页,应该被调出。实现这种算法,可在页表中增加一个“引用位”标志,记录该页自上次被访问以来经历的时间,每访问一次就重新计时。当产生缺页中断时,就调出计时值最大的那一页。对每一页的访问情况时时刻刻加以记录和更新,实现起来比较困难,开销也大。所以,实际应用中也可以采用页号队列的方法,且不需要指针。规定队首始终存放最久未使用的页,队尾总是最近被访问的页,每访问一页时就调整队列一次,把该页放到队尾,当产生缺页中断时,把队首的页给调出。
  3. 最近最不经常使用调度算法(Least Frequently Used,LFU)。为每一页设置一个计数器,每当访问一页就加 1,隔一个周期 T,所有计数器清 0。当发生缺页中断时,调出计数值最小的页,同时把所有计数器清 0。
  • 多级页表

       现代计算机普遍采用页式虚拟存储管理,且为用户提供较大的逻辑地址空间。例如,windows 2000 供用户使用的逻辑地址空间由 32 位组成,规定页面(即块的长度)为 4096(2^12) 字节,即页内地址占用了逻辑地址中的 12 位;余下的 20 位用于页号部分。允许用户程序最多可以使用 100 万个页面(2 的 20 次幂)。100 万个页面在页表中就要占 100 万个表项,这张页表就非常庞大。每个页表表项若以占用 4 个字节计算,则一张页表就要占用 400 万字节的连续存储空间,如果是多道并行工作,那么为每个用户都要建立一张页表,使得主存开销实在太大!

       实际上,程序的执行是有局部性的,一段时间里只会涉及一部分页,因此,没有必要把整张页表一直保存在主存中。现在,很多系统都采用多级页表结构,如 windows 2000 就采用了二级页表结构。以 32 位逻辑地址来阐述二级页表的远离。把 32 位逻辑地址分成 3 部分,其中 低 12 位是页内地址,高 20 位分成 2 部份,每一部分 10 位。其格式为:页号1(0~9)页号2(10~19)页内地址(20~31),由于逻辑地址是连续的,所以这实际上是把页分成了 1024 个页面组,每一组又含有 1024 个页面,页号1 指出页面组的编号是 0~1023,页号2 指出了每个页面组内的页面编号是 0~1023!

       建立页表时,第一级是页面组表(一级页表),第二级是组内页面表(二级页表,每组一张,供 1024 张)。一级页表指出二级页表的存放地址,二级页表指出页的存放地址。若每个表项占用 4 个字节,那么每一张页表就是 4096 字节,正好与主存块的大小一致,即每一个主存块正好可以被用来存放一张页表。

       采用二级页表结构的系统总是把页表保存在辅助存储器中。程序执行时先把一级页表装入主存储器。进行地址转换时,按逻辑地址中的页号1 查询一级页表,找出对应表项,可知二级页表是否已在主存中,若不在,则应将其加入,之后按页号2 查找页所在位置,若不在主存中也需将页调入主存,之后根据对应的主存块号和逻辑地址中的页内地址得到主存绝对地址。

       采用二级页表结构后,不需把页表一次性装入主存储器,且各页表可以分散存放在主存块中,必要时还可以将暂时不用的页表调出主存,有利于主存空间的利用。但在进行地址转换时增加了访问主存的次数,会影响指令执行速度,在进行页面调入调出时也会增加系统开销。所以,在采用二级页表的系统中,均会使用高速缓冲存储器来加快地址转换过程。还可扩充为三级、四级或更多级的页表。级别越多,灵活性越大,但管理的复杂性和系统开销也越大。

 

各种管理方式下的地址转换和存储保护表

管理方式

重定位方式

地址转换(操作系统执行)

地址转换(硬件执行)

存储保护

单用户连续

静态

绝对地址 = 逻辑地址 + 界限地址

 

界限地址 <= 绝对地址 <= 主存最大地址

固定分区

静态

绝对地址 = 逻辑地址 + 分区始址

 

分区始址 <= 绝对地址 <= 分区始址 + 分区长度

可变分区

动态

分区始址 –> 基址寄存器

分区末址 –> 限长寄存器

绝对地址 = 逻辑地址 + 基址寄存器值

基址寄存器值 <= 绝对地址 <= 限长寄存器值

页式

动态

建立页表

表中设置访问标志

绝对地址 = 块号 * 块长 + 页内地址

核对访问权

 

TEST

1. 解释下列术语:逻辑地址、绝对地址、地址转换。

主存空间的地址编号称为主存储器的绝对地址。

为方便用户,每个用户都可以认为自己作业的程序和数据存放在一组从 0 开始的连续空间中,用户程序中使用的地址称为逻辑地址。

处理器必须按照绝对地址去访问主存储器才能保证程序的正确运行,因此,必须把分配给用户作业的主存空间的地址进行重定位,即要把逻辑地址转换成绝对地址,这种转换的工作就称为重定位或地址转换。

      

2. 存储保护的目的是什么?怎样实现存储保护?

存储保护的目的是笔描主存储其中各作业相互干扰。

实现存储保护必须由软件和硬件相互配合,限制各作业只能访问属于它自己的那些区域,对于共享区限制各作业只能读或执行,但不准写。

 

3. 什么叫重定位?重定位的方式有哪两种?

把逻辑地址转换成绝对地址的工作称为重定位。重定位有静态重定位和动态重定位两种方式。

 

4. 比较固定分区、可变分区、页式存储管理的优缺点。

固定分区:管理简单,适用于多道程序设计系统,但总是分配给作业一个不小于作业长度的分区,许多作业实际只占用分区的一部分,使得分区中总有一部分区域闲置不用,降低了主存空间的利用率。

可变分区:由于分区大小是按照作业实际需求量身定做,因此能克服固定分区方式中主存空间利用率不高的缺点。移动技术能集中分散的空闲区或便于作业动态扩充主存,但也会带来系统开销。

页式存储管理:能把用户作业的连续逻辑地址空间分散到若干不连续的主存区域,充分利用主存空间又可减少移动所花费的开销,还能采用虚拟存储管理技术,实现较小主存空间运行较大作业。

 

5. 采用可变分区方式管理主存时,为什么要引入移动技术?

主要有两个目的:(1)集中分散的空闲区。当主存储器中各个空闲区的长度都不能满足作业,而这些空闲区长度之和又可以满足作业时,则可移动在主存储器中的作业,使各分散空闲区连成一片形成一个大的空闲区,从而将作业装入,使主存空间充分被利用。 (2)便于作业动态扩充主存。作业在执行中要求增加主存量时,只需适当移动临近作业就可增加它所占的连续区域。

 

6. 页式存储管理中为什么要设置页表?

主要是为了反映出逻辑地址中页号与主存中块号的映射关系,硬件地址转换机构根据查到的块号和页内地址能计算出主存中的绝对地址,确保程序正确执行。

 

7. 页式存储管理中页面大小是根据什么决定的?页表的长度又是根据什么决定的?

页面的大小由地址结构决定。低地址确定了页面的容量,即主存中块的大小;高位地址确定了逻辑地址的页数,即主存的块数。页表的的长度等于装入主存中的页数。

 

8. 假定某计算机配置的主存储器容量为 1M,当采用页式虚拟存储管理时提供给用户使用的逻辑地址空间为 4M,主存储器被分成长度为 4K 的等长块,请回答下列问题:(1)主存储器一共被划分成多少块?(2)用户作业最多可以有多少页?(3)画出该系统地址结构示意图。

(1)主存储器的容量为 1M,即 1024K,主存储器被分成 4K 的等长块,即一共被划分成 256 块。

(2)用户使用的逻辑地址空间为 4M,即 4 x 1024K,而主存储器块的长度为 4K,页的大小必须与块的大小相同,则用户作业最多有 1024 页。

(3)地址结构:页号 + 页内地址,共1024页,将占用地址高10位;页内地址为 4K,将占用低地址12位,整个地址的长度有22位。

 

9. 叙述页式存储管理中的地址转换过程。

作业执行过程中,处理器每执行一条指令,地址转换机构就按逻辑地址中的页号查询页表得到该页对应的块号,再按 块号 x 块长 + 页内地址 计算得到绝对地址。实际上,由于二进制乘法的特性,只需要把查询得到的块号作为绝对地址的高位,把页内地址作为绝对地址的低位,就能得到主存储器的绝对地址。

 

10. 什么叫虚拟存储器?

允许用户的逻辑地址空间大于主存储器的绝对地址空间,对于用户来说,就好像计算机系统具有一个容量很大的主存储器,这就称为虚拟存储器。

 

11. 叙述页式存储管理实现虚拟存储的基本原理。

将作业的全部信息作为副本存放在磁盘上,作业调度选中一个作业时,至少把作业的第一页信息装入主存储器,当作业执行过程中欲访问不在主存储器中的页时,再把它们装入。

 

12. 采用可变分区方式管理主存时,能实现虚拟存储器吗?为什么?

不能。单用户连续方式、固定分区方式和可变分区方式都不能实现虚拟存储器。前两者没有硬件的地址转换机构支撑,而可变分区方式中的硬件地址转换机构把绝对地址不在限定范围时作地址错误处理,所以只有页式存储管理可采用虚拟存储管理技术为用户提供虚拟存储器。

 

13. 什么叫抖动?怎样衡量页面调度算法的好坏?

如果选择了一个不合适的算法,就会出现这样的情况:刚被调出的页立即又要使用,因而又要把它调入;而调入不久又被调出;调出不久又被调入。如此反复,使调度非常频繁,以至于大部分时间花在来回调度上,这种现象就称为抖动,又称颠簸。

常用的页面调度算法有:先进先出、最近最久未使用、最近最不经常使用等。应根据作业的情况来具体选择一种恰当的调度算法,能尽量减少和避免抖动现象的算法就是好的,反之则是坏的。

 

14. 假定某计算机系统的主存容量为 32K,对主存采用动态定位可变分区分配算法。现有 3 个作业在主存中(如图),当作业 J2 执行时,要求动态扩充 3K 主存。为满足这一作业要求,应移动几道作业的信息?写出移动它们的次序、方向和距离。

图:操作系统(0~3),空闲区(4~5),J1(6~11),空闲区(12),J2(13~21),空闲区(22),J3(23~29),空闲区(30~32)

移动的方式有 2 种,方式一:J1 向上移动 1K,J2 向上移动 2K。方式二:J3 向下移动 2K。方式二好,因为只需要移动一次。

 

15. 某采用页式存储管理的系统接收了一个共 7 页的作业,作业执行时依次访问的页为:1,2,3,4,2,1,5,6,2,1,2,3,7。若把开始 4 页装入主存,当分别用先进先出(FIFO)调度算法和最近最久未使用(LRU)调度算法时,作业执行过程中会产生多少次缺页中断?写出依次产生缺页中断后应淘汰的页。

先进先出调度算法:产生 6 次缺页中断,调度过程为:1234 –> 5234 –> 5634 –> 5624 –> 5621 –> 3621 –> 3721,依次淘汰的页是:1,2,3,4,5,6。

最近最久未使用调度算法:产生 4 次缺页中断,1234 –> 1342 –> 3421 –> 4215 –> 2156 –> 1562 –> 5621 –> 5612 –> 6123 –> 1237,依次淘汰的页是:3,4,5,6。

 

16. 在一个采用页式虚拟存储管理的系统中,有一用户作业依次要访问的字地址序列是:115,228,120,88,446,102,321,432,260,167。若该作业的第 0 页已经装入主存,现分配给该作业的主存共 300 字,页的大小为 100 字,则当页面调度算法采用先进先出调度算法时将产生多少次缺页中断?缺页中断率为多少?

页的的大小为 100 字,分配给作业的主存为 300 字,即可用主存为 3 块。依访问的字地址序列可得知,访问页的顺序为:1,2,1,0,4,1,3,4,2,1。采用先进先出调度算法时,将产生 5 次缺页中断,中断率为 50%。

 

17. 某采用页式存储管理的系统,把主存分为大小为 128 字节的相等长度的块。有一个用户要把一个 128 x 128 的数组置成初值 0,在分页时把数组中的元素每一行放在一页中。假定给用户可用来存放数组信息的工作区只有一块(即只能存放数组中的一行元素)。用户用 Pascal 语言编写了如下两个不同的程序来实现数组的初始化,问分别运行这 2 个程序时,在实现数组初始化的过程中各会产生多少次缺页中断?

(1)var A : array [ 1..128] of array [ 1..128] of integer;

       for j := 1 to 128

         do for i = 1 to 128

           do A[i][j] := 0;

(2)var A : array [ 1..128] of array [ 1..128] of integer;

       for i := 1 to 128

         do for j = 1 to 128

           do A[i][j] := 0;

假定第一页已经放入主存储器中,那么:

程序1的初始化过程为:A[1][1],A[2][1],A[3][1]…,128 次的内层循环中将产生 127 次缺页中断,外层循环 128 次,则一共会产生 128 x 128 - 1 = 16383 次缺页中断。

程序2的初始化过程为:A[1][1],A[1][2],A[1][3]…,内层循环不会产生缺页中断,每一次的外层循环会产生 1 次缺页中断,则一共会产生 127 次缺页中断。

你可能感兴趣的:(存储管理 - 操作系统概论)