经过多年探索,人们提出了分层存储器体系(memory hierarchy)的概念,即在这个体系中,计算机有若干兆(MB)快速、昂贵且易失性的高速缓存(cache), 数千兆(GB)速度与价格适中且同样易失性的内存,以及几兆兆(TB)低速、廉价、非易失性的磁盘存储,另外还有诸如 DVD 和 USB 等可移动存储装置**。操作系统的工作是将这个存储体系抽象为一一个有用的模型并管理这个抽象模型。**
操作系统中管理分层存储器体系的部分称为存储管理器(memory manager)。它的任务是有效地管理内存,即记录哪些内存是正在使用的,哪些内存是空闲的;在进程需要时为其分配内存,在进程使用完后释放内存。
内存管理的主要功能:
- 内存空间的分配与回收
- 地址转换
- 内存空间的扩充
- 内存共享
- 存储保护
基础知识
逻辑地址与物理地址空间
程序的装入,实现逻辑地址到物理空间地址的转换。
物理地址 :加载到内存地址寄存器中的地址,内存单元的真正地址。在前端总线上传输的内存地址都是物理内存地址,编号从 0 开始一直到可用物理内存的最高端。物理地址是明确的、最终用在总线上的编号,不必转换,不必分页,也没有特权级检查
逻辑地址 :CPU 所生成的地址。逻辑地址是内部和编程使用的、并不唯一。例如,你在进行 C 语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址(偏移地址),不和绝对物理地址相干。
程序的链接与装入
创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序,通常需要以下几个步骤:
- 编译:由编译程序将用户源代码编译成若干目标模块。
- 链接:由链接程序将编译后形成的一组目标模块及它们所需的库函数链接在一起,形成一个完整的装入模块。
- 装入:由装入程序将装入模块装入内存运行。
程序的链接
- 静态链接:在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块) ,之后不再拆开。
- 装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式。
- 运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
装入方式
绝对装入
灵活性极低,只适用于单道程序环境
在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
可重定位装入(静态重定位)
在一般情况下, 一个作业在装入时分配到的内存空间和它的地址空间是不一-致的,因此,作业在CPU上运行时,其所要访问的指令、数据的物理地址和逻辑地址是不同的。显然,若在作业装入或执行时,不对有关的地址部分加以相应的修改,则会导致错误的结果。这种将作业的逻辑地址变为物理地址的过程称为 地址重定位。
静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间 ,如果没有足够的内存,就不能装入该作业。作业一旦进入内存,运行期间就不可以移动 。可重定位是指在装入时把逻辑地址转换成物理地址,但装入后不能改变
在多道程序环境下,多个目标模块的起始地址通常都从 0 开始,程序中的其他地址都是相对于起始地址的,此时应采用可重定位装入方式。根据内存的当前情况,将装入模块装入内存的适当位置。 在装入时对目标程序中指令和数据地址的修改过程称为重定位,又因为地址变换通常是在进程装入时一次完成的,故称为静态重定位。
动态运行时装入(动态重定位)
编译、链接后的装入模块的地址都是从 0 开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行 ,因此装入内存后所有的地址依然是逻辑地址。这种方式需要一个重定位寄存器的支持。
内存空间的分配和回收
- 内部碎片,是指分配给某进程的内存区域中,如果有些部分没有用上。
- 外部碎片,是指内存中的某些空闲分区由于太小而难以利用。
连续分配管理方式
连续分配:指为用户进程分配的必须是一个连续的内存空间。
单一连续分配
在单一连续分配方式中,内存被分为系统区和用户区。系统区通常位于内存的低地址部分,用于存放操作系统相关数据;用户区用于存放用户进程相关数据。内存中只能有一道用户程序,用户程序独占整个用户区空间。只支持单道程序。
优点:实现简单;无外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护。
缺点:只能用于单用户、单任务的操作系统中;有内部碎片,存储器利用率极低。
固定分区分配
将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业,这样就形成了最早的、最简单的一种可运行多道程序的