本系列博客重点在深圳大学操作系统课程的核心内容梳理,参考书目《计算机操作系统》(有问题欢迎在评论区讨论指出,或直接私信联系我)。


梗概

本篇博客主要介绍操作系统第四章存储器管理与第五章虚拟存储器的相关知识。

目录

一、存储器管理概述

1.存储器的层次结构

2.程序的装入与链接

2.1 装入

2.1.1 静态重定位

2.1.2 动态重定位

2.2 链接

3.内存分配

3.1 单一连续分配

3.2 固定分区分配

3.3 动态分区分配

3.3.1 首次适应算法(FF)

3.3.2 循环首次适应算法(CF)

3.3.3 最佳适应算法(BF)

3.3.4 最坏适应法(WF)

3.3.5 快速适应法(分类搜索法)

3.3.6 内存分配算法例题

3.4  可重定位分区分配

4.对换

二、分页分段存储管理

1.基本分页存储管理方式

1.1 简介

1.2 地址变换机构

1.3 地址变换例题 - 一级页表

1.4 两级页表与多级页表

1.5 两级页表与多级页表 - 习题

2.基本分段存储管理方式

2.1 简介

2.2 地址变换机构 

2.3 信息共享

2.4 分段存储管理 - 例题

3.段页式存储管理方式

三、存储器管理例题

四、虚拟存储器

1.简介与实现

2.请求分页系统存储管理方式

3.页面置换算法

3.1 最佳页面(OPT)置换算法

3.2 先进先出(FIFO)页面置换算法

3.3 最近最久未使用(LRU)页面置换算法 

3.4 Clock置换算法

3.5 改进型Clock置换算法 

3.6 最少使用置换算法LFU

4.请求分段存储管理方式

五、虚拟存储器例题


int main(void) {         int a;     printf(“%p”,&a);     return 0; }

这个程序打印出的a的地址,是真实的还是虚幻的?

虚拟地址!

如何对存储器进行有效管理(存储管理对象主要是内存)是很重要的,因为内存是很关键很紧张的资源。

一、存储器管理概述

1.存储器的层次结构

为满足速度、容量与成本的三重要求,存储器一般是多层的。

高层的存储器往往是速度很快、但成本高使容量有限,而接近底部的存储器容量很大、成本低,相对访问速度则慢。

存储管理的主要目的是为用户使用提供便利,充分发挥内存的利用率,让尽量多的用户程序调入内存运行

⑴.用户只需在自己的逻辑空间内编程,不需要了解自己将放在内存中的物理位置,也不需要了解其它用户程序在内存中的物理位置

⑵.为用户提供充分大的存储空间(虚存管理) 

操作系统为了有效管理计算机内存资源,一般具备以下几大功能:

1、内存分配:分配与回收

2、地址映射:逻辑地址->内存空间中的物理地址

3、存储保护:确保每道程序都在自己的内存空间运行,互不干扰(且不被用户侵犯)

4、内存扩充:从逻辑上扩充内存容量

5、提高主存储器的利用率:减少不可用的存储空间(称为“零头),允许多道程序动态共享主存。

2.程序的装入与链接

程序在系统中运行,必须先装入内存,再变为可执行程序执行,核心步骤为(1)编译(2)链接(3)装入

2.1 装入

对于程序的装入,一般有三种方式:

1、绝对装入方式:

核心:通过绝对地址将目标模块装入指定位置

通常是宁可在程序中采用符号地址,然后在编译或汇编时,再将这些符号地址转换为绝对地址。(也可由程序员直接赋予,但数据修改地址要随之变化,很麻烦) - 适用于小的计算机系统

2、可重定位装入方式:

对于多道程序环境,可重定位装入更合理,可根据内存的具体情况装入适当位置

重定位,通常来说把在装入时(作业地址->内存空间)对目标程序中指令和数据地址修改的过程称为重定位。

2.1.1 静态重定位

原指令作用:把相对地址为2500的存储单元的内容365装入1号累加器。

静态重定位是在程序执行之前进行重定位。在图中以“0”作为参考地址的装配模块,要装入以10000为起始地址的存储空间。显然在装入程序之前,程序必须做一些修改才能正确运行(2500->12500,1000->11000)

实现方式:将重定位项表中每一项(重定位项:需要修改的地址的位置)+重定位因子(本案例就一项) 

  • 优点:无须硬件支持
  • 缺点:程序重定位后无法在内存中移动,要求程序的存储空间是连续的。

说明:重定位表中列出所有修改的位置。如:重定位表的150表示相对地址150处的内容为相对地址(即100为从0起头的相对位置)。在装入时,要依据重定位后的起头位置(2000)修改相对地址。 重定位修改:重定位表中的150->绝对地址2150(=2000+150) 内容修改:内容100变成2100(=100+2000))。

2.1.2 动态重定位

动态重定位是指在程序执行过程中进行地址重定位,即在每次访问内存单元前才进行地址变换。不需装配模块的修改,需要硬件——重定位寄存器的支持。 

核心:由重定位寄存器中的存储管理部件MMU完成地址变换

优点:⑴目标程序装入内存时无需任何修改,所以装入之后再移动也不会影响其正确运行,这便于存储器用紧缩来解决存储器的碎片问题。⑵一个程序由若干个相对独立的目标模块组成时,每个目标模块各装入一个存储区域,这些存储区域可以不相领接,只要各个模块有自己对应的重定位寄存器就可以了。 

2.2 链接

程序编译后,得到一组目标模块,链接的功能是将目标模块装配成完整的装入模块,根据链接时间的不同,可以分为以下三种:

1、静态链接方式:

核心:程序运行前事先链接。

对于以上这个例子,需要解决两个问题:

(1) 对相对地址(0)进行修改。        (2) 变换外部调用(B、C)符号。 

2、装入时动态链接方式:

核心:程序边装入边链接。

优点为:(1)便于修改和更新。 (2) 便于实现对目标模块的共享。

3、运行时动态链接方式:

对上述在装入时链接方式的一种改进。这种链接方式是将对某些模块的链接推迟到执行时才执行,亦即,在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS去找到该模块并将之装入内存

优点:省空间、速度快

3.内存分配

为了能将用户程序装入内存,需要进行内存的分配,最早出现的存储器分配方式为连续分配,即为用户分配一个连续的内存空间,主要分为四类。

3.1 单一连续分配

一个用户程序独占连续的内存用户区

只能用于单用户、单任务的OS中

系统分两个内存区:系统区和用户区

3.2 固定分区分配

将内存划分为多个区域,每个内存区存放一个用户程序

可用于多用户、多任务环境 

对于分区的方法,可以采用两种:

1、相等大小分区:

  • 优点:简单
  • 缺点:大程序装不下,小程序浪费严重

2、不等大小分区:

  • 优点:适应性较强
  • 缺点:特别大的程序可能仍装不下

而内存分配的方式主要是使用内存分区使用表

区号

大小

始址

状态

1

8K

16K

可用

2

16K

24K

可用

3

32K

40K

可用

4

64K

72K

可用

5

120K

136K

可用

算法(后续详解):

⑴、首次适应算法(FF):按序选择第一个满足要求的内存区

⑵、最佳适应算法(BF):仅当与程序大小相当的分区空闲时才予分配

3.3 动态分区分配

  • 优点:可以按照用户进程实际大小,动态地分配内存空间,提高内存的使用效率
  • 缺点:不管采用何种算法,都必将产生小的、不可利用的空闲分区(碎片)

动态分区分配中三个需要明晰的问题分别是1)数据结构、2)回收操作、3)分配算法

1、分配所用数据结构:

数据结构主要用于记录内存使用情况,可采用两种形式:

2、回收操作:

根据待回收区与其他空闲分区的相邻情况区分操作:

若有相邻空闲分区,则合并,并修改大小与首址。

对于下图第三种情况,将回收区与前、后空闲分区F1、F2合并,用F1首址作为新空闲区的首址,大小为三空闲区之和,并取消F2表项

 

若回收区不与任何空闲区邻接,建立一个新表项,填写回收区的首址和大小,并插入空闲链表中适当的位置 

3、分配算法:

3.3.1 首次适应算法(FF)

核心:按序选择第一个满足要求的内存区

  • 优点:保留高地址部分的大空闲区
  • 缺点:低地址存在很多小的、无法利用的空闲分区,且查找时间较长 
3.3.2 循环首次适应算法(CF)

核心:从上次找到空闲分区的下一个分区开始,按序选择第一个满足要求的内存区

  • 优点:空闲分区在内存中均匀分布,查找时间少
  • 缺点:缺乏大的空闲分区 
3.3.3 最佳适应算法(BF)

核心:在整个空闲空闲分区中查找大小与用户程序大小最相近的空闲分区    

Tips:为了加快查找速度,将空闲分区链表从小到大排列

  • 优点:提高了内存使用效率,保留大的空闲区
  • 缺点:存在许多很小的、无法利用的空闲分区
3.3.4 最坏适应法(WF)

核心:要求空闲区按大小递减的次序组织空闲区表或队列,分配方式与最佳适应相反

  • 优点:当程序装入内存中最大的空闲区剩下的空闲区较大,还能装较大的程序。每次仅做一次查找。
3.3.5 快速适应法(分类搜索法)

核心:将空闲区根据其容量大小进行分类,对于每一类具有相同容量的所有空闲分区(空闲区的大小一般是2幂次方),单独设立一个空闲分区链,分配时,根据进程大小,寻找适合的最小空闲区的链进行分配

  • 优点:查找效率高,不需要分割,不容易产生碎片
  • 缺点:分区回归主存,系统开销较大,分配时会存在内存浪费(以空间换时间)
3.3.6 内存分配算法例题

有一作业序列,要求用首次,最佳,最坏适应法分析 哪种算法最合适。

例题补充:动态分区分配算法+实例详解_给定6个内存分区:300kb、600kb、350kb、200kb、750kb和125kb(按顺序),_Devour123的博客-CSDN博客

3.4  可重定位分区分配

上文提到,无论是什么分配方式长时间运行都会产生大量难以利用的小的内存空间分区,故需要进行紧凑(拼接)。

紧凑:对内存中正在使用的分区搬迁,使多个小空闲分区(碎片)合并为一个大的空闲分区

而为了实现紧凑(拼接),需要有有动态重定位机制支持,核心是重定位寄存器(存放进程首址)。 

动态重定位分区分配算法架构如下:

总体来说与动态分区分配算法流程一致,多的一步是分配失败时做判断,若所有小空闲分区和大于需求,则作紧凑后分配,反之返回分配失败

4.对换

对换是指把内存中暂不能运行的进程,或暂时不用的数据,换出到外存上,以腾出内存空间 

  • 整体对换:以进程为单位 (挂起操作)
  • 部分对换:以页或段为单位 (虚拟存储器) ,又分为页面对换与分段对换

对于对换空间的管理, 将外存分为文件区和对换区,对换区是连续的外存存储区。

整体对换可以采用与连续内存分配类似的方法,实现对换空间的管理(分配和回收)

而对于进程的换入换出主要操作如下:

1、进程换出:

  • 选出被换出的进程:首先选择阻塞进程,然后选择低优先级的就绪进程
  • 换出过程:换出非共享的程序段及数据段

2、进程换入:

  • 对就绪且换出进程,先申请内存,成功则换入
  • 失败则先换出其他进程,再继续申请换入

二、分页分段存储管理

所有的内存分配策略都受到外部碎片化的影响
外部碎片化:随着进程的加载和从内存中移除,空闲的内存空间被分割成小块。当有足够的总内存空间来满足请求,但可用空间不连续时,就会出现外部碎片
统计分析,即使有一些优化,给定N个分配的区块,另外0.5N个区块会因碎片化而丢失。
也就是三分之一的内存可能无法使用! 这一特性被称为 50%规则

Tips:紧凑的开销很大。
解决外部碎片问题的可能办法是,允许进程的逻辑地址空间不连续。因此,允许一个进程在任何有空间的地方被分配物理内存。

两种互补的技术实现了这个解决方案:分页、分段、组合 

内存离散分配方式:将一个进程分散地分配到许多不相邻接的分区中的内存分配方式

离散分配方式主要包括: 1、分页存储管理(将用户程序地址空间分为若干固定大小区域“页”/“页面”,也将内存空间分为若干物理块或页框,实现离散分配) 2、分段存储管理(将用户程序地址空间分为若干大小不同的段,段不邻接,段中含一组相对完整信息,分配时以段为单位。) 3、段页式存储管理(结合1、2优点,目前广泛应用) 

1.基本分页存储管理方式 - 重点

1.1 简介

分页的一个好处是可以共享共同的代码,特别是时间共享环境。

以下将分别介绍基本分页存储管理的核心概念:
1、页面:

将进程的逻辑空间分成若干大小相等的片,称为页面、或页

同一进程的页面按序从小到大进行编号,称页号

2、内存物理块:

将内存空间分成若干大小相等的存储块,称为物理块

内存块号按序从小到大进行编号,称块号 

3、进程页面与内存物理块关系:

进程页面大小与内存物理块大小完全相等 页大小 = (内存)块大小

进程的任何页面可以存放在内存任何物理块中(离散分配)

除进程最后一个页面外,其他页面都刚好装进一个内存物理块中

4、页面大小的选择:

页面大小通常在512字节~4k字节之间

页面大小是2的指数幂使地址映射过程非常容易 

5、进程地址结构:

进程地址A分为两部分:页号P与页内地址d

页内地址位数 = 页大小(本例为4KB)

页号P:P = INT(A/L) = (逻辑地址/页大小)取整

页内地址d:d = A MOD L = 逻辑地址 取余 页大小

如A=2170B,L=1KB,则P=2,d=122

6、页表:

页表记录进程每一页在内存中存放的块号,即记录进程页面与内存物理块号之间映射关系

1.2 地址变换机构

1.1的5中提到了进程地址结构,为了能将用户地址中的逻辑地址转换为内存空间中的物理地址,需要地址变换机构。其实际任务为页号到物理块号的转变,借助页表完成。

1、基本地址变换机构:
页表一般存放在内存中

页表的始址和页表的长度存放在进程PCB中

在进程执行时,页表的始址和页表的长度送入页表寄存器PTR 

  • 当进程要访问某个逻辑地址时,分页地址机构自动将逻辑地址分为页号与页内地址
  • 如果页号大于页表长度,越界错误
  • 将页表始址与页号和页表项长度的乘积相加,得页表中位置
  • 从页表中相应位置,得到物理块号,送入物理地址寄存器的内存物理块字段中
  • 将逻辑地址的页内地址部分送入物理地址寄存器的块内地址字段中 

缺点:访问一次逻辑地址,必须两次访问内存(先得到物理地址,再送数据进入

第一次访问内存为取得逻辑地址对应的内存物理地址

第二次访问内存为取得逻辑地址中的数据 

2、具有快表(TLB)的地址变换机构:

快表:具有并行查寻能力的特殊高速存储器,也称为“联想存储器”

快表的查找速度一般为内存访问的数倍,如快表访问一次费时20ns,而内存可能需要100ns

将页表放在快表中,将可以节省从逻辑地址到物理地址的映射时间

从快表中找页号对应的块号,省去计算

  • 分页地址机构自动将逻辑地址分为页号与页内地址
  • 越界检查
  • 将页号送入快表中进行并行查找,如果从快表中找到所需页号,则将快表中对应的物理块号送物理地址寄存器
  • Tips:因为快表受限于成本,不能做得太大,所以存在找不到的情况。
  • 否则将页表始址与页号和页表项长度的乘积相加,得页表中位置,进而得到物理块号,送入物理地址寄存器的内存物理块字段中
  • 页内地址送入物理地址寄存器

Tips: 因为基本地址变换机构需要访问两次内存(找地址+改数据)。

1.3 地址变换例题 - 一级页表

假设页长为1KB(1024字节),逻辑地址为2500(十进制)。利用页表把逻辑地址变换成物理:

(1)将虚地址分离成页号P和页内地址d:

页号P=(逻辑地址/页大小)取整

页内地址d=逻辑地址 mod 页大小   

(2)根据页号查页表,由页表项读出块号:    由页号 P=2查页表得块号为5

(3)块号和页内地址构成物理地址:  

物理地址=块号×页大小+页内地址

= 5*1024+452 =5572

1.4 两级页表与多级页表

当逻辑地址空间非常大(2^32-2^64)时,一级页表将变得非常大

如每个页面大小为4KB,逻辑地址空间为2^32时,需要2^20(即1M)页表项,每个页表项占用4个字节,每个进程共需要4MB页表(连续内存空间)

故引入多级页表,从两级页表开始,其操作方式即将页表以离散方式放入内存

Tips:外层页表存放页表存放的位置,页内地址的位数 = 页面大小,外层页内地址的位数 = 一级页表页表项 除以 2(or 二级页表页表项)

上图说明(左右两个页表分别对应页表与页对应内容的物理块,第0页页表存放在1011物理块中,第0页存放在1物理块中)

两级页表的地址变换机制如下,增设了一个外层页表寄存器:

Tips:对于64位机器,采用两级页表是不合理的,将会有42位用于外层页号,占用大量内存,需要多级页表。

1.5 两级页表与多级页表 - 习题

有一基本分页存储管理系统,内存块大小为512Bytes,每个块号占用4个Bytes。(1)如果页表也以离散方式放在内存中,求采用一级页表和两级页表,系统能支持文件的逻辑空间最多为多少?(2)假如逻辑地址为12345H,求页内地址和外层页号

(1)每个内存块占4Bytes,即每个页表项占4B 每个内存块大小为512Bytes, 每个内存可放下最多512/4=128个页表项 采用一级页表能支持文件的逻辑空间最多为:128x512=64KBytes(逻辑地址 = 块号 x 页大小 + 页内偏移) 采用二级页表能支持文件的逻辑空间最多为:128x128x512=8MBytes 

(2)512占用9bits,即页内地址占9bits 128占7bits,即外层页内地址占7bits 12345H=0001,0010,0011,0100,0101b

页内地址=后9bits=1,0100,0101b=145H 外层页号=(9+7)bits以上地址=0001b=1H

 一个32位地址的计算机系统使用二级页表,虚地址被分为9位顶级页表,11位二级页表(偏移).请问: 1)页面长度是多少? 2)空间共有多少个页面?

  • 页面长度:  32-9-11=12
  • 页面大小:  2^12=2^2*2^10=4KB
  • 页面个数: 2^9*2^11 = 2^20

补充:对于一级页表,页面个数 = 页号位数(多少页) , 对于二级页表,页面个数 = 外层页号位数(页表数) * 外层页内地址位数(每个页表页数)

在一个分页存储管理系统中,逻辑地址长度为16位,页面大小为4096字节,现有一逻辑地址为2F6AH,且第0、1、2页依次存在物理块10、12、14号中,问相应的物理地址为多少?

2F6AH的二进制表示:0010 1111 0110 1010,前四位为页号2。

物理地址:14*2^12+ 1111 0110 1010 =EF6AH 

设一页式管理系统,向用户提供的逻辑地址空间最大为16页,每页2048字节,内存中共有8个存储块。试问逻辑地址至少应为多少位?内存空间有多大?

假设页面的大小为4KB,一个页表项用4B.若要求用页表来管理地址结构为34位的虚拟地址空间,并且每个页表只占用一页。那么,采用多级页表结构时,需要几级才能达到管理的要求?

34位的虚拟地址空间大小为:16GB

本题即求不同多级列表的最大能支持文件的逻辑空间,算法与第一题类似。

页的大小为4KB,一个页表项用4B,每个页表只占用一页。这表示:

一个页表有1024个表项,可以管理1024个页面,即管理4M大小的虚存空间。

  • 第1级一个页表,管理1K个页面,1K个页面的存储量是4MB  => 一级页表不能管理16GB的虚拟空间
  • 进入第2级;第2级有1K个页表,管理1K*1K个页面,1K*1K个页面的存储量是4GB  => 二级页表仍不能管理16GB的虚拟空间
  • 进入第3级;第3级有1K*1K个页表,管理1K*1K*1K个页面,1K*1K*1K个页面的存储量是4096GB  =>三级页表能管理16GB的虚拟空间

2.基本分段存储管理方式

在过往OS发展中,为了提高内存的利用率,存储管理方式从连续分配方式中的固定分区分配到动态分区分配,再到离散分配方式中的分页存储管理,但为了满足程序员在编程与使用上多方面的要求,分段存储管理方式出现了。

如对上图这一程序使用分页存储管理是不合适的,分页是固定大小的, 一个页面中可能装有两个不同子程序段的指令代码,共享/存储等方式不确定,增大了各种开销。

2.1 简介

  • 基本概念

分段是指将一个进程划分为多个具有逻辑意义而且相对独立的部分,例如主程序段、数据段、堆栈段、子程序段等,每个段都是从0开始的独立逻辑地址空间

  • 引入分段的好处

方便编程 信息共享 信息保护 动态增长 动态链接

1、分段地址结构:

作业(进程)由多个段组成 每个段(从0开始)独立编址 整个作业(进程)的地址是二维结构 每个段有一个唯一的名称(一般用段号来代表) 

2、段表:

段表记录进程每一段在内存中存放的(开始)地址及段的大小

2.2 地址变换机构 

1、基本地址变换:

  • 当进程要访问某个逻辑地址时,先取得段号
  • 如果段号大于段表长度,越界错误
  • 将段表始址与段号和段表项长度的乘积相加,得段表中位置
  • 从段表中相应位置,得到段的首址及段的长度
  • 如段内地址大于段长度,越界错误(比分页存储管理多的一步越界判断)
  • 将段的内存首址与段内地址相加,得内存物理地址 
  • Tips:K = 1024

2、具有快表的地址变换机构:

与分页存储管理类似,为了访问段内数据,必须两次访问内存,故同样可以采用快表,将段表放入快表中

Tips:由于进程中,段的数目远比页的数目少,因此,所需要的段也比页面少,因此,访问快表的命中率也比较高,因此,采用快表的分段地址变换,一般仅比常规(单次)内存访问慢10%-15%

2.3 信息共享

由于段是信息的逻辑单位,含有一组有意义的相对完整的信息

因此,多个作业(进程)共享同一个有独立意义的段是非常方便的,只需在各自的段表中,标上相同的段基址和段长度即可

如Windows中的动态链接库中的纯代码段,可同时被多个进程共享

可以看到分段系统共享信息是便利于分页系统的。

总的来说,分页分段主要区别如下:

页是信息的物理单位(满足系统管理的需要)   段是信息的逻辑单位(满足用户的需要)

页的大小固定(由系统决定)    段的大小不固定(由用户决定)

分页的作业(进程)地址是一维的    分段的作业(进程)地址是二维的 

2.4 分段存储管理 - 例题

某系统采用分段式存储管理,在一个进程中,它的段表如下所示,求逻辑地址为(2,895)对应的物理地址(所有数据都是十进制)

段号

开始地址

0

80K

1

12K

2

25K

3

72K

1.如以下段表所示,请将逻辑地址(0,137),(1,4000),(2,3600),(5,230)转换成物理地址

段号    内存始址    段长
0    50K    10k
1    60K    3K
2    70K    5K
3    120K    8K
4    150K    4K

(0,137):0<=4,137<=10k,所以物理地址为:50*1024+137=51337

(1,4000):1<=4,但4000>3k,越界中断

(2,3600):2<=4,3600<=5k,所以物理地址为:70*1024+3600=75280

(5,230):因为5>4,越界中断

3.段页式存储管理方式

由于段是由用户按编程需要设定的,因此其大小不固定

段需要连续分配内存空间,因此,同样存在连续分配存储管理方式中存在的缺点

结合段与页式管理的优点,既节省内存空间,提高内存分配的效率,又兼顾用户编程的需要
1、基本原理: 

先将用户作业(进程)分成若干具有一定逻辑意义的段,再将段分成大小固定的若干个页

段页式系统需要同时设置段表和页表,段表中存放页表始址及页表大小

 2、段页式管理的地址结构:

 3、段页式地址变换机构: 

  • 当进程要访问某个逻辑地址时,先取得段号
  • 如果段号大于段表长度,越界错误
  • 将段表始址与段号相加,得段表中位置
  • 从段表中相应位置,得到该段页表的首址
  • 将段内页号与页表首址相加,得页表中位置
  • 从页表中相应位置,得到物理块号p
  • 将块号p与页内地址d组合成物理地址 

三次访问内存!!(访问段表取页表始址、访问页表取物理块号、取指令与数据)

可以增加高速缓冲寄存器,与前文原理类似。

例题如下:

在一个段页式存储管理系统,页面大小为1024字节。在一个进程中,它的段表、页表如下所示,求逻辑地址为(1,2099)对应的物理地址。

根据逻辑地址确定段号为1, < 2 未越界,根据段表找到对应页表为第33块。

根据逻辑地址确定段内页表页号为INT(2099 / 1024)= 2,未越界,页内地址为2099 MOD 1024 = 51

根据段内页表(33)可知内存块(物理块)号为40,故物理地址 = 40 x 1024 + 51

三、存储器管理例题

至此,课本第四章存储器管理核心知识已解析完成,接下来解析一些相关例题。

要保证一个程序在主存中被改变了存放位置后仍能正确执行,则对主存空间应采用( )技术。

A.动态重定位 B.静态重定位 C.动态分配 D.静态分配

A

固定分区存储管理把主存储器划分成若干个连续区,每个连续区称一个分区。经划分后分区的个数是固定的,各个分区的大小( )。

A.是一致的 B.都不相同 C.可以相同,也可以不相同,但根据作业长度固定 D.在划分时确定且长度保持不变

D

采用固定分区方式管理主存储器的最大缺点是( )。

A.不利于存储保护 B.主存空间利用率不高 C.要有硬件的地址转换机构 D.分配算法复杂

B

采用可变分区方式管理主存储器时,若采用最优适应分配算法,宜将空闲区按( )次序登记在空闲区表中。

A.地址递增 B.地址递减 C.长度递增 D.长度递减 

C

在可变分区存储管理中,某作业完成后要收回其主存空间,该空间可能要与相邻空闲区合并。在修改未分配区表时,使空闲区个数不变且空闲区始址不变的情况是( )空闲区。

A.无上邻也无下邻 B.无上邻但有下邻 C.有上邻也有下邻 D.有上邻但无下邻

D or B (看地址是下往上增还是上往下增)

在可变分区存储管理中,采用移动技术可以( )。

A.汇集主存中的空闲区 B.增加主存容量 C.缩短访问周期 D.加速地址转换

A

页式存储管理中的页表是由( )建立的。 A.操作员 B.系统程序员 C.用户 D.操作系统

D

采用页式存储管理时,重定位的工作是由( )完成的。

A.操作系统 B.用户 C.地址转换机构 D.主存空间分配程序

C

采用段式存储管理时,一个程序如何分段是在( )决定的。

A.分配主存时 B.用户编程时 C.装入作业时 D.程序执行时

B

采用段式存储管理时,一个程序可以被分成若干段,每一段的最大长度是由( )限定的。 A.主存空闲区的长度 B.硬件的地址结构     C.用户编程时 D.分配主存空间时

B

假定某采用页式存储管理的系统中,主存容量为1M,被分成256块,块号为0,1,2,……255。现有一个共4页(页号为0,1,2,3)的作业被依次装人到主存的第2,4,1,5块中。请回答:

(1)主存地址应该用多少位来表示?

(2)作业每一页的长度为多少字节?逻辑地址中的页内地址部分应占用多少位?

(3)把作业中每一页占用的主存块起始地址填入下表。       

(4)若作业执行中要从第0页的第75单元和第3页的第548单元读信息,那么,实际应从主存的哪两个单元读信息?请把应访问的主存绝对地址用二进制编码的十六进制数表示。

(1)1M = 2^20Bytes,故主存20位来表示

(2)页大小 = 块大小 = 主存容量 / 块数 = 2^12 = 4K,页内地址部分需要12位。

(3)每一页对应的起始地址即4K*块号

(4)用每一页对应的起始地址((3)算的)+ 单元数(页内偏移)即为真实物理地址。

四、虚拟存储器

第四章介绍的各种方法都是实际存储器,有一个共同特点(一次性与驻留性):要求将一个作业全部装入内存方能运行,于是造成了两个问题(1)作业逻辑空间过大时不能被全部装入,导致无法运行、(2)由于内存容量的限制导致大量作业在外存上等待。

一个解决方案是增加内存容量,成本较高且收到机器本身的限制。

故虚拟存储器出现了。

1.简介与实现

实际上有许多作业在每次运行时,并非用到其全部程序,故可以仅把作业的一部分装入内存就能运行,这就是虚拟存储器系统实现的理论基础:程序执行的局部性规律。

程序在执行时将呈现出局部性规律,即在一段时间内,程序的执行仅局限于某个部分;相应地,它所访问的存储空间也局限于某个区域内。

  • 时间局限性:某指令被执行或某数据被访问,不久后可能再执行/访问(大量循环存在)
  • 空间局部性:程序访问了某个存储单元,附件的存储单元页将被访问(顺序执行)

虚拟存储器是采用请求调入和置换功能,将内存和外存统一管理,达到把作业的一部分装入内存便可运行,给用户提供的一个比内存容量大的一维的逻辑地址空间。

Tips:实现基础:多次性、对换性与虚拟性,逻辑容量由内外存之和决定,运行速度接近内存速度,成本接近于外存。 

而对于虚拟存储器的实现方法,为是作业多次装入/换出内存,均基于离散分配存储管理方式,主要是(1)分页请求系统(2)请求分段系统

2.请求分页系统存储管理方式

请求分页系统是在基本分页系统上增加了请求调页功能和页面置换功能(作业所需的部分程序装入即可启动运行,后续再通过调页进行内存的换入换出)形成的系统。

1、请求页表机制:

核心数据结构仍是页表,页表项结构(后四部分为增加)如下:

  • 状态位P:指示该页是否已调入内存
  • 访问字段A:记录本页在一段时间内被访问的次数
  • 修改位M:该页在调入内存后是否被修改过
  • 外存地址:该页在外存中的位置,通常是物理块号 

2、缺页中断机制:

请求分页系统中,若要访问的页面不在内存,便产生一缺页中断,请求OS将缺页调入内存。与一般的中断操作有两个方面不同:

(1)缺页中断是指令执行期间产生和处理中断信号

(2)一条指令在执行期间可能产生多次缺页中断

3、地址变换机构:

而用于地址转换(逻辑与物理地址的映射/重定位)仍是使用地址变换机构,基于基本的机构。

  • 分页地址机构自动将逻辑地址分为页号与页内地址
  • 越界检查
  • 将页号送入快表中进行并行查找,如果从快表中找到所需页号,则将快表中对应的物理块号送物理地址寄存器,并修改访问位和修改位
  • 否则将页表始址与页号和页表项长度的乘积相加,得页表中位置
  • 如果页面已在内存,修改快表;否则,调用缺页中断,从外存调入页面,并修改快表
  • 从快表中得到内存块号,送入物理地址寄存器,并修改访问位和修改位
  • 页内地址送入物理地址寄存器 

而对于请求分页中的内存分配,有一些问题需要解决:

1、最小物理块数的确定:

是指能保证进程正常运行所需的最小物理块数。当系统为进程分配的物理块数少于此值时,进程将无法运行。进程应获得的最少物理块数与计算机的硬件结构有关,取决于指令的格式、 功能和寻址方式。

对于某些简单的机器,若是单地址指令且采用直接寻址方式,则所需的最少物理块数为2。其中,一块是用于存放指令的页面,另一块则是用于存放数据的页面。如果该机器允许间接寻址时,则至少要求有3个物理块。对于某些功能较强的机器, 其指令长度可能是两个或多于两个字节,因而其指令本身有可能跨两个页面,且源地址和目标地址所涉及的区域也都可能跨两个页面。

2、物理块分配策略:

在请求分页系统中,可采取两种分配策略——固定和可变分配策略(给每个进程分配的物理块数量是否可变)。在进行置换时,也可采取两种策略——全局置换和局部置换(每次发现缺页是只换入换出一页(局部)还是一块(全局))。于是可组合成以下三种策略。

(1)固定分配局部置换策略:物理块数量难以确定

(2)可变分配全局置换策略:易实现,可能导致缺页率增加

(3)可变分配局部置换策略

3、物理块分配算法:

采用固定分配策略是,有如下几种物理块分配算法:

(1)平均分配算法:可供分配的物理块平均分给每个进程

(2)按比例分配算法:按进程大小比例分配

(3)考虑优先权的分配算法:给优先级高的进程分配更多物理块

而对于请求分页系统的性能分析,主要是参考缺页率(与有效访问时间成正比)

缺页率对有效访问时间的影响分析如下:

在请求分页系统中,假设存储器的访问时间Tr为100ns,缺页率为p为0.1%,缺页中断时间Tt为20ms。当页号在内存页表查到时存取内存一个数据时间为T1=Tr+Tr =2*Tr,而页面失效时存取内存一个数据时间为T2=Tr+Tt+Tr+Tr ≈ Tt 。 则有效访问时间就可以表示为:

有效访问时间(μs)                  

=(1一p)×T1十p×T2            

=(1一p)×0.2十p×20000                  

= 0.2十19999.8 p     

由上式可以看出,有效访问时间与缺页率成正比。如果缺页率为0.1%,则有效访问时间约为20μs,与直接访问存储器的有效访问时间(0.1μs)相比的时间,程序执行的性能将受到严重的影响,所以在虚拟存储系统中应该保持非常低的缺页率,同时选用高速磁盘和高速磁盘接口

3.页面置换算法 - 重点

当发生缺页时,需要请求OS将缺页调入内存,若内存无空闲,需调出页面到外存,而调出页面的选择算法,即页面置换算法

置换算法的好坏将直接影响系统的性能,不适合的算法可能导致发生”抖动“,即刚被换出的页面又要调入,增加开销。一个好的页面置换算法应具有较低的页面更换频率

3.1 最佳页面(OPT)置换算法

选择被置换的页面,将是永不使用的页面,或最长时间不使用的页面

Tips:是一种理想算法,通常作为标准评价其他算法的优劣

  • 优点:可保证最低的缺页率
  • 缺点:不可能真正实现(由于人们无法预知哪个页面在未来最长时间不被访问)

假定系统为进程固定分配三个物理块,且页面被访问顺序为:    

7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1

6次页面置换 

3.2 先进先出(FIFO)页面置换算法

选择最先进入内存的页面,即选择在内存中驻留时间最长的页面予以淘汰

  • 优点:算法简单
  • 缺点:性能不佳

假定系统为进程固定分配三个物理块,且页面被访问顺序为:    

7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1

12次页面置换 

在做题时,可采用压栈的方式(或设置一个循环替换指针),即把最早加入的(下次要替换的)放在最前面

Belady现象:采用FIFO算法时,如果对一个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多,缺页率反而提高的异常现象。对页面访问序列A B C D A B E A B C D E ,物理块从3块增加到4块,缺页次数增加。 

3.3 最近最久未使用(LRU)页面置换算法 

选择最近最久未被使用的页面淘汰

  • 优点:性能较好
  • 缺点:需要较多的硬件支持

假定系统为进程固定分配三个物理块,且页面被访问顺序为:    

7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1

9次页面置换 

在做题时,可采用压栈+换位的方式,即把最近最久未用的(下次要替换的)放在最前面

而在LRU的实现上需要硬件支持, 主要是移位寄存器和栈

1、移位寄存器:

⑴、采用移位寄存器记录每页的使用情况

⑵、数据格式:R=Rn-1Rn-2…R2R1R0

⑶、页面被访问一次,最高位Rn-1置1,每隔一定时间,寄存器右移一位

⑷、R值最小的页面,是将被调出的页面

本样例中,第3个内存页的R值最小,故缺页置换选择它。

2、栈:

⑴、采用特殊的栈来保存当前使用的各个页面的页面号

⑵、栈顶保留的是最新被访问的页

⑶、栈底保留的是最久未被访问的页 

一个例题如下:在一个请求分页系统中,假定系统分配给一个作业的物理块数为 3,并且此作业的页面走向为 2、3、2、1、5、2、4、5、3、2、5、2。试用 FIFO和 LRU 两种算法分别计算出程序访问过程中所发生_一个请求分页系统中,假如系统分配给一个作业的物理块数为3,且此作业的页面走向为2_Serendipity_筱楠的博客-CSDN博客https://blog.csdn.net/gl620321/article/details/106144536

3.4 Clock置换算法

LRU算法性能较好,但需要较多硬件支持,故一般使用LRU近似算法,如NRC。

Clock算法也称最近未用算法(NRC),设置1位访问位,记录页面是否被访问过(访问过为1,未访问为0) ,实现原理如下:

⑴、将内存所有页面用指针链成一个循环队列

⑵、Clock算法沿链查找页面

⑶、如果访问位为0,则换出

⑷、如果访问位为1,则将访问位复0;并继续沿链查找下一个页面,直到找到一个访问位为0的页面换出

3.5 改进型Clock置换算法 

改进型Clock置换算法除设置1位访问位(A),还设置1位修改位(M)

将页面分成四类:

⑴、1类:A=0,M=0,最佳淘汰页

⑵、2类:A=0,M=1,次佳淘汰页

⑶、3类:A=1,M=0

⑷、4类:A=1,M=1,最不应淘汰页

Tips:因为页面置换的代价比修改的大,故(2)为次佳淘汰页

实现原理如下:

⑴.查找指针前进一步,判断当前页是否为第1类页(A=0,M=0),是则选择该页淘汰

⑵.否则,继续沿链向下查找

⑶.如果沿链查找一周,没有第1类页面,则查找第2类页(A=0,M=1),找到后淘汰,并将访问过的页面访问位置为0(A=0)

⑷.如果沿链查找一周后,未找到第2类页面,则将所有页面的访问位置0,重新从第⑴步开始

在一个请求分页系统中,已知某进程有4页在内存,页码依次为12,26,35,40,其A、M位分别为(1,1)、(1,0)、(1,0)、(1,1),若采用改进型Clock置换算法,选择哪页淘汰?选择完成后,四个页的A、M位分别为多少?

选择完成后四个页的A、M分别为(0,1)、(0,0)、(0,0)、(0,1)

淘汰26 or 35页,与循环队列的顺序有关(本题未给出块号顺序)

3.6 最少使用置换算法LFU

核心:该算法选择使用次数最小的页面淘汰

该算法要求为每个页表项配置一个计数器(实际系统中用移位寄存器代替),一旦某页被访问,则页表项中的计数器值加1,在需要淘汰页面时,选择其计数器值最小的页面淘汰(相同时淘汰最早进入页面,即变为FIFO)。

4.请求分段存储管理方式

请求分段存储管理同样是基于基本分段存储管理,先调入部分分段即可启动运行,在后续再进行段的调入调出,也需要一定硬件支持。

1、请求段表机制:

核心的数据结构仍是段表(前三个是之前有的)

  • 存取方式:执行、只读、读/写
  • 访问字段A:记录本段在一段时间内被访问的次数
  • 修改位M:本段在调入内存后是否被修改过
  • 存在位P:指示本段是否已调入内存
  • 外存地址:本段在外存中的位置,通常是起始盘块号
  • 增补位:指示运行过程中是否进行过动态增长 

2、缺段中断机制:

当需要访问的段不在内存时,便产生一缺段中断

与缺页中断的相同点: ⑴.缺段中断同样可能发生在指令执行过程中 ⑵.一条指令执行期间,可能发生多次缺段中断

与缺页中断的不同点: ⑴.一条指令只可能存在于一个段中 ⑵.一个(组)数据只可能存在于一个段中

3、地址变换机制: 

4、分段共享与保护:

第四章提到分段的出现是满足用户(程序员)的编程需求,方便编程 信息共享 信息保护 动态增长 动态链接,在请求分段存储管理中为了实现分段共享,减少共享段的调进调出次数,应增加配置共享段表,用来对共享段进行管理

共享进程计数器COUNT:记录有多少个进程需要共享该分段。

存取控制字段:说明不同的进程对该分段不同的存取权限。

段号:对于同一个共享段,不同的进程可以使用不同的段号去共享该段。 

而对于共享段的分配与回收,简介如下:

  • (1)分配

在为共享段分配内存时,对第一个请求使用该共享段的进程,由系统为该共享段分配一物理区,再把共享段调入该区,同时将该区的始址填入请求进程的段表的相应项中,还须在共享段表中增加一表项,填写有关数据,把count置为1,之后,当又有其它进程需要调用该共享段时,由于该共享段已被调入内存,故此时无须再为该段分配内存,而只需在调用进程的段表中,增加一表项,填写该共享段的物理地址;在共享段的段表中,填上调用进程的进程名、存取控制等,再执行count=count+1操作,以表明有两个进程共享该段。

  • (2)回收

当共享此段的某进程不再需要该段时,应将该段释放,包括撤消该进程段表中相应表项,以及对共享段所对应的表项执行count =count一1操作。若结果为0,则须由系统回收该共享段的物理内存,以及取消在共享段表中该段所对应的表项。

五、虚拟存储器例题

至此,第五章虚拟存储器的核心知识就已解析完成,接下来进行一些题目的解析。

某虚拟存贮器的用户编程空间共32个页面,每页1KB,主存为16KB。假定某时刻用户页表中已调入主存的页面的虚拟页号和物理页表对照表为表一,则下表中与虚拟地址相对应的物理地址为表二(如果主存找不到,即为该页失效)。  

A,B:①  页失效      ②  1E5C(H)           ③  2A5C(H)   ④  165C(H)       ⑤  125C(H)   ⑥  1A5C(H) 

A:⑤ B:①

选2:静态重定位是在作业的﹎﹎A﹎﹎中进行的,动态重定位是在作业的﹎﹎B﹎﹎中进行的。  A,B:(1)编译过程;(2)装入过程;(3)修改过程;(4)执行过程。

A:(2)B:(4)

选3:在首次适应算法中,要求空闲分区按﹎﹎A﹎﹎顺序链接成空闲分区链;在最佳适应算法中是按﹎﹎B﹎﹎顺序形成空闲分区链;最坏适应算法是按﹎﹎C﹎﹎顺序形成空闲分区链。  A,B,C:(l)空闲区首址递增;(2)空闲区首址递减;(3)空闲区大小递增;(4)空闲区大小递减。

A:(1)B:(3)C:(4)

选4:在请求分页内存管理的页表表项中,其中状态位供﹎﹎A﹎﹎时参考;修改位供﹎﹎B﹎﹎时参考;访问位供﹎﹎C﹎﹎时参考;外存始址供﹎﹎D﹎﹎时参考。  A,B,C,D:(l)分配页面;(2)置换算法;(3)程序访问;(4)换出页面;(5)调入页面。

A:(3)B:(4)C:(2)D:(5)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐