一、内存管理的基础知识
1. 内存的概念
内存可存放数据,程序执行前需要先放到内存中才能被 CPU 处理——缓和 CPU 与硬盘之间的矛盾;
扩展:
如果计算机“按字节编址”,那么每个存储单元大小为1字节,即1b,8个进制位;
如果字长为16位的计算机“按字编制”,则每个存储单元大小为1个字,每个字节为16个二进制位。
2. 进程运行的基本原理
我们写的代码要翻译成 CPU 能识别的指令,这些指令会告诉 CPU 应该去内存的哪个地址读/写数据,这个数据应该做什么样的处理。
2.1 逻辑地址 v.s. 物理地址
逻辑地址(相对地址):程序经过编译、链接后生成的指令中指明的是逻辑地址(相对地址),即:相对于进程的起始地址而言的地址。
2.2 从写程序到程序运行
编译:由编译程序将用户源代码编译成若干个目标模块(编译就是把高级语言翻译成机器语言);
链接:由链接程序将编译后形成的一组目标模块,以及所需函数链接在一起,形成一个完整的装入模块;
装入(装载):由装入程序将装入模块装入内存运行。
2.4 三种链接方式
静态链接:在程序运行之前,先将各目标模块以及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开;
装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式;
运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
2.5 三种装入方式
绝对装入:在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。注:绝对装入只适用于单道程序环境;
静态重定位:又称可重定位装入。编译,链接后的装入模块的地址都是从 0 开始的,指令中适用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当位置。装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的);
静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。作业一旦进入内存后,在运行期间就不能再移动,也不能再申请空间。
动态重定位:又称动态运行时装入。编译、链接后的装入模块的地址都是从 0 开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有所有的地址依然时逻辑地址。这种方式需要一个重定位寄存器的支持,采用动态重定位时允许程序在内存中发生移动。
二、操作系统的内存管理
操作系统作为资源的管理者,需要对内存进行管理,需要管理以下内容:
操作系统需要提供内存保护功能,保证各进程在各自存储空间内运行,互不干扰。
操作系统需要提供某种技术实现从逻辑上对内存空间进行扩充;
操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地址转化;
操作系统负责内存空间的分配与回收;
1. 内存保护
内存保护可采取两种方法:
方法一:在CPU中设置一对上、下限寄存器,存放进程的上下限地址。进程要访问某个地址时,CPU检查是否越界:
方法二:采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址:
2. 内存扩充
内存空间的扩充,包括了覆盖技术、交换技术以及虚拟存储技术。
2.1 覆盖技术
早期的计算机内存很小,因此经常会出现内存大小不够的情况。后来人们引入了覆盖技术,用来解决“程序大小超过物理内存总和”的问题。覆盖技术的思想:将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存。内存中分为一个“固定区”和若干个“覆盖区”。需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)。不常用的段放在“覆盖区”,需要用到时调入内存,用不到时调入内存。
必须由程序员声明覆盖结构,操作系统完成自动覆盖。缺点:对用户不透明,增加了用户编程负担。覆盖技术只用于早期的操作系统,现在已成历史。
2.2 交换技术
交换技术也称对换技术,其主要思想是:当内存空间紧张时,系统将内存中某些进程暂时换出外存,把内存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)。这也是中级调度所要做的,中级调度(内存调度)就是要决定将哪个处于挂起状态的进程重新调入内存。
交换技术的实现:
应该在外存(磁盘)的什么位置保存被换出的进程?
具有对换功能的系统中,通常把磁盘空间范围文件区和对换区两部分。文件区主要用于存放文件,主要追求空间的利用率,因此对文件区空间的管理主要采用离散分配方式;对换空间只占磁盘空间的小部分,被换出的进程数据就存放在对换区。由于对换的速度直接影响到系统的整体速度,因此对换区空间的管理主要追求换入换出速度,因此通常对换区采用连续分配方式。总之,对换区的 I/O 速度比文件区的更快。
什么时候应该交换?
交换通常在许多进程运行且内存吃紧时进行,而系统负荷降低时就暂停。例如:在发现许多进程运行时经常发生缺页,就说明内存紧张,此时可以换出一些进程;如果缺页率明显下降,就可以暂停换出。
应该换出哪些进程?
可优先换出阻塞进程;可换出优先级低的进程;为了防止优先级低的进程在被调入内存后很快又被换出,有的系统还会考虑进程在内存驻留的时间。
3. 内存空间的分配与回收
内存空间的分配与回收可分为两种方式,每种方式下面还有 3 种 实现方式:
连续分配管理方式
单一连续分配
固定分区分配
动态分区分配
非连续分配管理方式
基于分页存储管理
基本分段存储管理
段页式存储管理
注:连续分配是指为用户分配的必须是一个连续的内存空间。
下篇文章再详细介绍内存空间的几种分配方式。