3.1.1 内存管理的基本原理和要求
内存管理:操作系统对内存的划分和动态分配。
内存管理的功能:
功能 | 说明 |
---|---|
内存空间的分配与回收 | 由操作系统完成主存储空间的分配和管理,使程序员摆脱存储分配的麻烦,提高编程效率。 |
地址转换 | 在多道程序环境下,程序中的逻辑地址与内存中的物理地址不可能一致,因此存储管理必须提供地址变换功能,把逻辑地址转换为相应的物理地址 |
内存空间的扩充 | 利用虚拟存储技术和自动覆盖技术,从逻辑上扩充内存。 |
存储保护 | 保证各道作业在各自的存储空间内运行,互不干扰。 |
程序的装入和链接
创建进程首先要将程序和数据装入内存,将用户源程序变为可在内存中执行的程序。有以下三个步骤:
编译:由编译程序将用户源代码编译成若干目标模块。
链接:由链接程序,将编译后形成的一组目标模块及所需的库函数链接在一起,形成一个完整的装入模块。
装入:由装入程序将装入模块装入内存运行。
程序的链接有以下三种方式:
静态链接:在程序运行之前,先将各目标模块及他们所需的库函数链接成一个完整的可执行程序,以后不再拆开。
装入时动态链接:将用户源程序编译后所得到的一组目标程序再装入内存时,采用边装入边链接的方式。
运行时动态链接:对某些目标模块的连接是在程序执行中需要该目标模块时才进行的。其优点是便于修改和更新,便于实现对目标模块的共享。
逻辑地址与物理地址
编译后,每个目标模块都从0号单元开始编址,这称为该目标模块的相对地址(逻辑地址)。当链接程序将各个目标程序链接成一个完整的可执行目标程序时,链接程序顺序依次按各个模块的相对地址构成统一的从0号单元开始编址的逻辑地址空间。
物理地址空间是指内存中物理单元的集合,它是地址转换的最终地址,进程在运行时执行指令和访问数据,最后都要通过物理地址从主存中存取。当装入程序将可执行代码装入内存中,必须通过地址转换将逻辑地址转换为物理地址,这个过程称为地址重定位。
内存保护
(1)在CPU中设置一对上、下限寄存器,存放用户作业在主存中的下限和上限地址,每当CPU要访问一个地址时,分别和两个寄存器的值对比,判断有无越界。
(2)采用重定位寄存器和界地址寄存器来实现这种保护。重定位寄存器含最小的物理地址值,界地址寄存器含逻辑地址的最大值。每个逻辑地址值必须小于界地址寄存器。内存管理机构动态的将逻辑地址与界地址寄存器进行比较,若未发生地址越界,则加上重定位寄存器的值后映射成物理地址,再送交内存单元。
3.1.2 覆盖与交换
覆盖
由于程序运行时并非任何时候都要访问程序及数据的各个部分。因此,可把用户空间分成一个固定区和若干覆盖区,将经常活跃的部分放在固定区,其余部分按调用关系分段,首先将那些即将要访问到的段放入覆盖区,其他段放在外存中,在需要调用前,系统再将其调入覆盖区替换覆盖区中原有的段。
覆盖技术的特点是打破了必须将一个进程的全部信息装入主存后才能运行的限制。但当同时运行程序的代码量大于储存时,仍不能运行。此外,内存中能够更新的地方只有覆盖区的段,不在覆盖区的段会常驻内存。
交换
把处于等待状态的程序从内存移到辅存,把内存空间腾出来,这一过程称为换出,把准备好竞争CPU运行的程序,从辅存移到内存,这一过程又称换入。
3.1.3 连续分配管理方式
连续分配方式是指为一个用户程序分配一个连续的内存空间。
单一连续分配
内存在此方式下分为系统区和用户区,系统区仅供操作系统使用,通常在低地址部分;用户区是为用户提供的除系统区之外的内存空间,这种方式无需进行内存保护,因为内存中永远只有一道程序,因此肯定不会因为访问越界而干扰其他程序。
优点是简单,无外部碎片可以采用覆盖技术,不需要额外的技术支持。缺点是只能用于单用户单任务的操作系统,有内部碎片,存储器的利用率极低。
固定分区分配
固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干固定大小的区域,每个分区只装入一道作业,当有空闲分区时,便可在从外存的后备作业队列中选择适当大小的作业装入该分区,如此循环。
固定分区分配在划分队列中有两种不同的方式:
(1)大小相等的分区:用于利用同一台计算机去控制多个相同对象的场合,缺乏灵活性。
(2)大小不等的分区:划分为多个较小的分区、适量的中等分区和少量大分区。
为便于内存分配,通常将分区按大小排队,并为之建立一张分区说明表。其中个表象包括每个分区的初始地址、大小及状态。
分区号 | 大小/KB | 起址 | 状态 |
---|---|---|---|
1 | 12 | 20 | 已分配 |
2 | 32 | 32 | 已分配 |
3 | 64 | 64 | 已分配 |
4 | 128 | 128 | 已分配 |
这种分区方式存在两个问题:一是程序可能太大而放不进任何一个分区中,这时用户不得不使用覆盖技术来使用内存空间;二是主存利用率低,当程序小于固定分区大小时,也独占一个完整的内存分区空间,这样分区内部就存在空间浪费,这种现象称为内部碎片。
固定分区是可用于多道程序设计的最简单的存储分配,无外部碎片,但不能实现多进程共享一个主存区,所以存储空间利用率低。
动态分区分配
不预先划分内存,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。
随着进程的换入/换出,在内存中会产生越来越多的碎片,如上图的6MB,4MB。这些小的内存快成为外存碎片。克服外部碎片可以通过紧凑技术来解决。即操作系统不断地对进程进行移动和整理,但这需要动态重定位寄存器的支持,且相对费时。
在进程装入或换入主存时,若内存中有多个足够大的空闲块,则操作系统必须确定分配哪个内存块给进程使用,这就是动态分区的分配策略。有以下几种算法:
- 首次适应算法:空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。
- 最佳适应算法:空闲分区以容量递增的方式形成分区链,找到第一个能满足要求的空闲分区。
- 最坏适应算法:空闲分区以容量递减的次序链接,找到第一个能满足要求的空闲分区。
- 邻近适应算法:由首次适应算法演变而成,不同在于分配内存时从上次查找结束的位置开始继续查找。