3.1 内存管理基础与连续分配
内存管理的功能;程序的编译、链接与装入(绝对装入、静态重定位、动态重定位);逻辑地址与物理地址、进程的内存映像;内存保护与共享;覆盖与交换;单一连续分配、固定分区分配与动态分区分配(首次、邻近、最佳、最坏适应)及其回收;内部碎片与外部碎片。
内存管理的功能
操作系统对内存的划分和动态分配就是内存管理,主要功能有:
- 内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理,使程序员摆脱存储分配的麻烦;
- 地址转换:把程序中的逻辑地址转换为内存中的物理地址;
- 内存空间的扩充:利用覆盖、交换或虚拟存储技术,从逻辑上扩充内存;
- 内存共享:允许多个进程访问内存的同一部分;
- 存储保护:保证各道作业在各自的存储空间内运行,互不干扰。
程序的链接与装入
用户源程序要变为可在内存中执行的程序,通常要经过三步:
- 编译:由编译程序把源代码编译成若干目标模块;
- 链接:由链接程序把目标模块以及它们所需的库函数链接在一起,形成一个完整的装入模块。链接后形成完整的逻辑地址;
- 装入:由装入程序把装入模块装入内存运行。
| 链接方式 | 时机 | 特点 |
|---|---|---|
| 静态链接 | 程序运行之前 | 把各目标模块及库函数链接成一个完整的可执行文件,以后不再拆开 |
| 装入时动态链接 | 装入内存时 | 边装入边链接,便于修改和更新,便于实现对目标模块的共享 |
| 运行时动态链接 | 程序执行中需要某模块时 | 只链接用得到的模块,加快装入过程,节省内存空间 |
| 装入方式 | 地址转换的时机 | 特点 |
|---|---|---|
| 绝对装入 | 编译时就产生绝对地址 | 只适用于单道程序环境,程序必须装入指定位置 |
| 可重定位装入(静态重定位) | 装入时一次性地把逻辑地址修改为物理地址 | 必须一次分配作业所需的全部连续内存空间;作业装入后在运行期间不能移动,也不能再申请内存 |
| 动态运行时装入(动态重定位) | 程序真正执行时才把逻辑地址转换为物理地址,需要重定位寄存器的支持 | 程序可以分配到不连续的存储区;运行时可以在内存中移动;便于共享 |
逻辑地址与物理地址
编译后,每个目标模块都从 0 号单元开始编址,这称为该目标模块的相对地址(逻辑地址);链接后,整个程序有一个从 0 开始编址的逻辑地址空间。用户程序和程序员只需知道逻辑地址,而物理地址是内存中实际存储单元的地址。进程运行时看到和使用的都是逻辑地址,由地址转换(重定位)机构把它变为物理地址。
一个进程在内存中的映像通常包括:代码段(只读,可以被多个进程共享)、数据段(全局变量和静态变量)、进程控制块(存放在系统区)、堆(动态分配的内存,向高地址增长)、栈(函数调用时的局部变量、参数和返回地址,向低地址增长)。
内存保护
内存分配前要保护操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。常用两种方法:
- 在 CPU 中设置一对上、下限寄存器,存放用户作业在主存中的上限和下限地址,每当 CPU 要访问一个地址时,分别和两个寄存器的值相比较,判断有无越界;
- 采用重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器):重定位寄存器存放进程的最小物理地址,界地址寄存器存放进程的最大逻辑地址。访问内存时,先把逻辑地址与界地址寄存器比较,若未越界,再加上重定位寄存器的值得到物理地址。
加载重定位寄存器和界地址寄存器必须使用特权指令,只有操作系统内核才能加载。
覆盖与交换
- 覆盖:把用户空间分成一个固定区和若干个覆盖区,经常活跃的部分放在固定区,其余部分按调用关系分段,即将访问的段放入覆盖区,其他段放在外存。覆盖必须由程序员声明覆盖结构,对用户不透明,现在已很少使用。
- 交换(对换):把处于等待状态(或在 CPU 调度原则下被剥夺运行权)的进程从内存移到外存,把内存空间腾出来,这一过程称为换出;把准备好竞争 CPU 的进程从外存移到内存,称为换入。中级调度就是采用交换技术。交换通常在许多进程运行且内存吃紧时进行,换出的进程放在外存的对换区(连续分配,读写速度比文件区快)。
覆盖是在同一个程序或进程中进行的;交换是在进程(作业)之间进行的,对用户透明。
连续分配管理方式
连续分配为一个用户程序分配一个连续的内存空间。
单一连续分配
内存分为系统区和用户区,用户区内存中仅有一道用户程序,整个用户区为一个用户独占。实现简单、无外部碎片,可以采用覆盖技术扩充内存;但只能用于单用户、单任务的操作系统,有内部碎片,存储器的利用率极低。
固定分区分配
把用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业。分区可以大小相等,也可以大小不等。系统建立一张分区说明表,每个表项记录分区的大小、起始地址和状态(是否已分配)。
固定分区是最简单的多道程序存储管理方式。它的问题是:程序可能太大而放不进任何一个分区,只能采用覆盖技术;程序小于分区时,分区中未被利用的空间就成了内部碎片,主存利用率低。
动态分区分配
动态分区(可变分区)不预先划分内存,而是在进程装入内存时,根据进程的实际需要动态地为它分配内存,使分区的大小正好适合进程的需要。系统中分区的大小和数目都是可变的。
随着进程不断地装入和退出,内存中会出现许多小的空闲分区,它们都太小而无法分配出去,这些称为外部碎片。外部碎片可以通过紧凑(拼凑)技术解决:操作系统不时地对进程进行移动和整理,这需要动态重定位寄存器的支持,而且相对费时。
系统用空闲分区表或空闲分区链记录空闲分区。把一个新作业装入内存时,按某种分配算法从空闲分区中选出一个分区:
| 算法 | 空闲分区的组织 | 特点 |
|---|---|---|
| 首次适应(FF) | 按地址递增次序,找到第一个能满足要求的分区 | 最简单,通常也是最好、最快的;低地址部分会留下许多小碎片,每次查找都要经过它们 |
| 邻近适应(NF,循环首次适应) | 按地址递增,从上次查找结束的位置开始找 | 会使高地址的大分区也被分割,通常比首次适应差 |
| 最佳适应(BF) | 按容量递增,找到第一个能满足要求的(即最小的)分区 | 看起来最好,但会留下许多难以利用的小碎片,外部碎片最多 |
| 最坏适应(WF) | 按容量递减,总是挑最大的分区 | 很快就没有可用的大分区,性能很差 |
回收分区时,要根据回收区与相邻空闲分区的位置关系进行合并,共有四种情况:① 回收区与前一个空闲分区相邻,合并后修改前一个分区的大小;② 与后一个空闲分区相邻,合并后修改后一个分区的起始地址和大小;③ 与前、后两个空闲分区都相邻,三者合并为一个分区,并删除后一个分区的表项;④ 前后都不相邻,为回收区单独建立一个新表项。
即时练习
- 1某基于动态分区存储管理的计算机,其主存容量为 55 MB(初始为空闲),采用最佳适配(Best Fit)算法,分配和释放的顺序为:分配 15 MB,分配 30 MB,释放 15 MB,分配 8 MB,分配 6 MB,此时主存中最大空闲分区的大小是( )。
- 2分区分配内存管理方式的主要保护措施是( )。
- 3在虚拟内存管理中,地址变换机构将逻辑地址变换为物理地址,形成该逻辑地址的阶段是( )。
- 4某计算机按字节编址,其动态分区内存管理采用最佳适应算法,每次分配和回收内存后都对空闲分区链重新排序。当前空闲分区信息为:起始地址 20 K、大小 40 KB;500 K、80 KB;1000 K、100 KB;200 K、200 KB。回收起始地址为 60 K、大小为 140 KB 的分区后,系统中空闲分区的数量、空闲分区链第一个分区的起始地址和大小分别是( )。
- 5下列存储管理方式中,会产生内部碎片的是( )。
Ⅰ. 分段虚拟存储管理 Ⅱ. 分页虚拟存储管理 Ⅲ. 段页式分区管理 Ⅳ. 固定式分区管理 - 6下列关于动态重定位的叙述中,正确的是( )。
标记完成后,侧栏会显示进度。进度仅保存在本浏览器中。