313_覆盖与交换
# 3.1_3_覆盖与交换
各位同学大家好。在这个小节中我们会学习覆盖与交换相关的一些知识点
在之前的小节中我们已经学习到了操作系统,对内存进行管理,需要实现这样 4 个功能,地址转换和存储保护是上个小节详细介绍过的。这个小节我们会介绍两种实现,内存空间的扩充的技术,覆盖技术和交换技术,虚拟存储技术会在之后用更多的专门的视频来进行讲解。
# 覆盖技术
首先来看一下覆盖技术,在早期的计算机当中内存一般来说是很小的,比如说 IBM 推出的第一台个人计算机,只支持一兆字节大小的内存,大家现在使用的这些程序像什么 QQ 微信这些可以自己去电脑上看一下,一般来说都很少有低于 100 兆字节的这种程序,所以可想而知一兆字节的大小,很多时候应该是不能满足这些程序的运行的。
那么后来人们为了解决这个问题,就引入了覆盖技术,就是解决程序大小超过物理内存总和的问题。
比如说一个程序本来需要这么多的内存空间,但实际的内存大小又只有这么多,怎么办呢?覆盖技术的思想就是要把程序分成多个段,或者可以理解为就是多个模块,然后常用的段就需要常驻内存,不常用的段需要只有在需要的时候才需要调入内存。内存当中会分一个固定区和若干个覆盖区,常用的那些段需要放在固定区里,并且调入之后就不再调出,除非运行结束。这是固定区的特征,不常用的段就可以放在覆盖区里,只有需要的时候才需要调入内存,也就是调入内存的覆盖区,然后用不到的时候就可以调出内存。
我们来看一个具体的例子,假设有这样一个程序,它有这样的一系列调用结构,就是 A 这个模块会依次调用 b 模块和 c 模块,注意是依次调用,也就是说 b 模块和 c 模块,只可能被 a 这个模块在不同的时间段调用,不可能是同时访问 b 和 c 这两个模块。
同样的 b 模块有可能会调入调用到 d 模块,然后 c 模块有可能会依次调用到 e 模块和 f 模块,那么如果我们的程序是这样的,调用结构的话,我们采用覆盖技术就可以进行这样的设置,我们可以把包含 main 函数的模块 a 放到一个固定区里,那么固定区就是 a 模块的大小,也就是 8k。
另外由于 b 模块和 c 模块不可能同时被访问,也就是说在同一个时间段内,内存当中要么有 b,要么有 c 就可以了,不需要同时存在 b 和 c这两个模块,所以我们可以让 b 和 c 这两个模块共享一个覆盖区,覆盖区的大小以 b 和 c 这两个模块当中更大的模块为准,也就是 10k。因为如果我们把覆盖区设为 10k 的话,既可以存得下 c 也可以存得下 b
同样的 def 这几个模块也不可能同时被使用,所以这几个模块也可以像上面一样共享一个覆盖区覆盖 1,它的大小就是按它们之间最大的也就是 d 模块的大小 12k 来计算。
所以如果说我们的程序有一个明显的这种调用结构的话,那么我们可以根据它这种自身的逻辑结构,让这些不可能被同时访问的程序段共享一个覆盖区,只有其中的某一个模块需要被使用的时候,这个模块才需要放到覆盖区里。所以如果没有采用覆盖技术的话,那么这个程序要全部放入内存,需要 8+8+10+12+4+10 等于很多 k 大家可以自己算一下。但是如果采用覆盖技术的话,我们只需要用 10+8+12,也就是总共 30k 的大小,就可以让这个程序顺利的运行了。
所以采用了覆盖技术之后,在逻辑上看这个物理内存的大小是被拓展了的,不过这种技术也有一个很明显的缺点,因为这个程序当中的这些调用结构,其实操作系统肯定是不知道的,所以程序的这种调用结构必须由程序员来显性的声明,然后操作系统会根据程序员声明的这种调用结构,或者说覆盖结构来完成自动覆盖。所以这种技术的缺点就是对用户不透明,增加了用户编程的负担因此。覆盖技术现在已经很少使用了,它一般就只用于早期的操作系统中,现在已经退出了历史的舞台。
# 交换技术
接下来我们再来看一下交换技术,交换技术在有的地方又称作为对换技术,它的设计思想是当内存空间紧张的时候,系统可以把内存当中的某些进程暂时换出外存,把外存当中已经具备运行条件的进程换入内存。所以其实采用这种技术的时候,进程是在内存与磁盘或者说外存之间动态的调度的。
之前咱们已经提过,其实已经提到过一个和交换技术息息相关的知识点,咱们在第二章讲处理机调度的时候,讲过一个处理机调度层次的概念,分为高级调度、中级调度和低级调度,其中,中级调度就是为了实现交换技术而使用的一种调度策略
就是说本来我们的内存当中有很多进程正在并发的运行,如果某一个时刻突然发现内存空间紧张的时候,我们就可以把其中的某些进程把它暂时换出外存,而进程相关的 PCB 会保留在内存当中,并且会插入到所谓的挂起堆列里,一直到之后内存空间不紧张了,内存空间充足的时候,又可以把这些进程相关的数据再给换入内存。
那为什么进程的 PCB 需要常驻内存呢?因为进程被换出外存之后,其实我们必须要通过某种方式记录下来进程到底是放在外存的什么位置。这个信息也就是进程的存放位置,这个信息我们就可以把它记录在与它对应的这些 PCB 当中,操作系统就可以根据 PCB 当中记录的这些信息对这些进程进行管理了,所以进程的 PCB 是需要常驻内存的。
那么中级调度或者说内存调度,其实就是在交换技术当中选择一个处于外存的进程,把它换入内存这样一个过程。
讲到这个地方,大家也需要再回忆一下低级调度和高级调度分别是什么?既然提到了挂起,我们就再来回忆一下和挂起相关的知识点,暂时换出外存等待的那些进程的状态,称之为挂起状态,或者简称挂起态。那挂起态又可以进一步细分为就绪挂起和阻塞挂起两种状态。在引入了这两种状态之后,我们就提出了一种叫做进程的七状态模型,如果一个本来处于就绪态的进程被换出了,外存进程就处于就绪挂起态。如果一个本来处于阻塞的进程被换出外存的话,那么进程就处于阻塞挂起态。七状态模型相关的知识点,咱们在第二章当中已经进行过补充,这就不再赘述。大家可以再结合这个图回忆一下这些状态之间的转换是怎么进行的,特别是中间的这三个最基本的状态之间的转换。
所以采用了交换技术之后,如果说某一个时刻内存内的空间不够用了,那么我们可以把内存当中的某一些进程数据暂时换到外存里,再把某一些更紧急的进程数据放回内存,所以交换技术其实也在逻辑上扩充了内存的空间。那么接下来我们再思考三个问题,
- 第一,我们把这些进程数据放到了外存或者说磁盘当中,我们应该放到外存的什么位置呢?
- 第二,我们应该在什么时候进行交换?
- 第三,我们在进行交换的时候应该选择哪种进程把它换出?
先来看第一个问题,在现代计算机当中外存一般来说就是磁盘。具有对换功能或者说交换功能的操作系统当中,一般来说会把磁盘的存储空间分为文件区和对换区这样两个区域,文件区主要是用来存放文件的,主要是需要追求存储空间的利用率,所以在对文件区一般来说是采用离散分配的方式,这个地方一会再做解释。
对换区的空间一般来说只占磁盘空间的很小的部分,注意被换出的进程数据一般来说就是存放在对换区当中的,而不是文件区。由于对换区的换入换出速度会直接影响到各个进程并发执行的这种速度。所以对于对换区来说,我们应该首要追求换入换出的速度,因此对换区通常会采用连续分配的方式,这个地方大家理解不了,咱没有关系,咱们在第四章文件管理的章节会具体的再进一步学习什么是对换区,什么是文件区,并且到时候大家就能够理解,为什么离散分配方式可以更大的提高存储空间的利用率,而连续分配方式可以提高换入换出的速度,这个地方大家只需要理解一个结论,对换区的 IO 速度或者说输入输出的速度是要比文件区更快的,所以我们的进程数据被换出的时候,一般是放在对换区,换入的时候也是从对换区再换回内存,这就回答了我们的第一个问题。
再看第二个问题,我们在什么时候应该进行交换?一般来说交换会发生在系统当中,有很多进程在运行,并且内存吃紧的时候,在这种时候我们可以选择换出一些进程来腾空内存空间,一直到系统负荷明显降低的时候,就可以暂停换出。比如说如果操作系统在某一段时间发现许多进程运行的时候都经常发生缺页,这就说明内存的空间不够用,所以这种时候就可以选择换出一些进程来腾空一些内存空间。如果说缺页率明显下降,也就是说看起来系统负荷明显降低了,我们就可以暂停换出进程了。这个地方涉及到之后的小节会讲到的缺页,还有缺页率这些相关的知识点,这儿理解不了没有关系,大家能够有个印象就可以了。
第三个问题,我们应该换出什么进程,这个地方我们给出一些参考的思路。
- 首先我们可以考虑优先换出一些阻塞的进程,因为处于就绪态的进程,其实是可以投入运行的,而处于阻塞它的进程,即使是在内存当中,反正它暂时也运行不了,所以我们可以优先把阻塞进程调出换到外存当中。
- 第二,我们可以考虑换出优先级比较低的进程,不用解释很好理解。
- 第三,如果我们每次都是换出优先级更低的进程的话,那么就有可能导致优先级低的进程,刚被调入内存很快又被换出的问题,这就有可能会导致优先级低的进程饥饿的现象。所以有的系统当中为了防止这种现象,会考虑进程在内存当中的驻留时间,如果如果一个进程在内存当中驻留的时间太短,进程就暂时不会把它换出外存。这个地方再强调一点,PCB 是会常驻内存的,并不会被换出外存。所以其实所谓的换出进程,并不是把进程相关的所有的数据,一个部落的全部都调到外存里,操作系统为了保持对这些换出进程的管理, PCB 这个信息还是需要放在内存当中,那么这就是交换技术。
# 小结
这个小节我们学习了覆盖技术和交换技术相关的知识点,这两个知识点一般来说只会在选择题当中进行考察,大家只要能够理解这两种技术的思想就可以了。
那么可能稍微需要记忆一点的就是固定区和覆盖区相关的这些知识点,在固定区当中的程序段,在运行过程当中是不会被调出的。而在覆盖区当中的程序段在运行当中,在运行过程当中是有可能会根据需要进行调入调出的。另外如果考察了覆盖技术的话,那么很有可能会把覆盖技术的缺点作为其中的某一个选项进行考察。
在讲解交换技术的过程当中,我们补充了文件区和对换区相关的知识点,这些会在第四章中进行进一步的学习,这个地方大家只需要知道,换出的进程的数据一般来说是放在磁盘的对换区当中的。
最后我们再来看一下覆盖与交换这两种技术的一个明显的区别。其实覆盖技术是在同一个程序或者进程当中进行的,通过之前咱们讲解的例子,这句话现在也不难理解,相比之下交换技术是在不同进程或作业之间进行的,暂时运行不到的进程可以调出外存,比较紧急的进程可以优先被再重新放回内存。