在存储体系中,我们采用的是“分层存储器体系”(memory hierarchy),即将存储分为高速缓存(cache)、内存、磁盘存储、可移动存储装置(U盘、DVD等)。
当我们直接操作物理地址的时候,会带来严重的问题。第一,如果用户程序可以寻址内存的每个字节,那么操作系统就很容易被破坏,导致操作系统停止运行。第二、使用该模式,想要同时运行多个程序是非常困难的,因为地址之间非常容易相互影响。要保证多个应用程序同时处于内存中而不相互影响,需要解决两个问题:保护和重定位。
由于上面的问题存在,我们引入了地址空间的概念,地址空间就是一个进程可用于寻址内存的一套地址集合。每个进程都有一个自己的地址空间,并且这个地址空间独立于其他进程的地址空间(特殊情况下进程需要共享它们的地址空间除外)。
我们利用动态重定位的方式,将每个进程的地址空间映射到物理内存的不同的地方。其中,我们处理的方法是给每个CPU配置两个特别的硬件寄存器,分别是基址寄存器和界限寄存器。当一个进程运行时,程序的起始物理地址装载到基址寄存器,程序的长度装载到界限寄存器。在我们很多实际系统中,对基址寄存器和界限寄存器会以一定的方式加以保护,使得操作系统才能更改它们。
使用基址寄存器和界限寄存器的缺点:每次访问内存都要进行加法和比较运算。其中加法运算在没有特殊电路时,非常耗时。
但是我们的内存是有限的,为防止内存超载,我们采用交换技术和虚拟内存。本文主要介绍交换技术。
交换技术(swapping):即把一个进程完整调入内存,使进程运行一段时间,然后将其存会磁盘。
交换的过程如上图所示,开始时内存中只有进程A。之后创建进程B和C或者从磁盘将它们换入内存。图d表示将A换到磁盘。然后D被调入,B调出,最后A再次被调入。由于A的位置发生变化,所以在它换入的时候通过软件或在程序运行期间通过硬件对其地址进行重定位。
交换的过程中会在内存中产生多个空闲区,那就需要专门的技术对这些空闲区进行管理。常用的技术有以下几种:
第一种是使用位图的存储管理,使用位图方法时,内存可能被划为成小到几个字或大到几千字节的分配单元。每个分配单元对应于位图中的一位,0表示空闲,1表示占用。一块内存区和其相应的位图如下所示。
第二种是用链表的存储管理,维护一个记录已分配内存段和空闲内存段的链表。如上图C所示,链表中的每一个结点都包含以下域:空闲区(H)或进程(P)的指示标志、起始地址、长度和指向下一结点的指针。
当按照地址顺利在链表中存放进程或空闲区时,有以下这些算法来为创建的进程分配内存: 首次适配法、下次适配法、最佳适配算法、最差适配算法、快速适配算法。
其中快速适配算法就是为那些常用大小的空闲区维护单独的链表;最差适配算法就是总是分配最大的可用空闲区,使新的空闲区比较大从而可以继续使用;最佳适配算法是搜索整个链表,找到能够容纳进程的最小的空闲区。