内存管理的基本概念
链接与装入
将一个用户源程序变为一个可在内存中执行的程序,通常要经过以下几步:
(1)编译:由编译程序(Compiler)对用户源程序进行编译,形成若干个目标模块(Object Module);
(2)链接:由链接程序(Linker)将编译后形成的一组目标模块以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module);
(3)装入:由装入程序(Loader)将装入模块装入内存。
装入
1.绝对装入方式(Absolute Loading Mode)
装入模块中用实际地址,装入预定地方。适用于单道环境。
2.可重定位装入方式(Relocation Loading Mode)
- 装入模块中为相对地址,可由重定位装入程序在装入时一次修改为绝对地址。适用于多道环境。
- 把在装入时对目标程序中指令和数据地址的修改过程称为重定位。
- 地址变换通常是在装入时一次完成的,以后不再改变该地址,此变换过程称为静态重定位。
3.动态运行时的装入方式(Dynamic Run-time Loading)
- 可重定位方式,不允许程序在运行时在内存中移动位置,但实际运行中,程序在内存中的位置可能要改变。
- 动态运行时装入程序在把装入模块装入内存后,并不立即把装入模块中的逻辑地址转换为物理地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存后的所有地址都仍是逻辑地址。
- 为使地址转换不影响指令的执行速度,这种方式需要一个重定位寄存器的支持。
链接
源程序经过编译后,可得到一组目标模块。链接程序的功能是将这组目标模块以及它们所需要的库函数装配成一个完整的装入模块。
1.静态链接方式(Static Linking)
在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的装配模块,以后不再拆开。我们把这种事先进行链接的方式称为静态链接方式。
2.装入时动态链接(Load-time Dynamic Linking)
目标模块在装入内存时,采用边链接边装入的方式。即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存。
- 便于修改和更新
- 便于实现对目标模块的共享
3.运行时动态链接(Run-time Dynamic Linking)
连续内存分配方法
单一连续分配
只能用于单用户、单任务的操作系统中。
1.系统区仅提供给OS使用,它通常是放在内存的地址部分。
2.用户区内存中仅装有一道用户程序,即整个内存的用户空间由该程序独占。
3.优点:简单易行 ;缺点:内存、CPU利用率低。
固定分区分配
它将内存空间划分为若干个固定大小的区域,每个分区大小可相同,也可不同。OS占一区,其余每个分区中可以装入一道作业。
划分分区的方法:
(1)分区大小相等:缺乏灵活性
(2)分区大小不等
内存分配:
(1)将分区从小到大排队,并为之建立一张分区使用表
(2)当有程序要装入时,检索该表,找出能满足大小的分区,修改分配位;若未找到,失败。
动态分区分配
装入和处理过程中建立分区,使其大小和作业大小相等,分区数和大小都可变。
数据结构
- 空闲分区表:在系统中设置一张空闲分区表,用于记录每个空闲分区的情况。
- 空闲分区链:在每个分区的起始部分设置一些用于控制分区分配的信息,以及用于链接各分区所用的前向指针,在分区尾部则设置一向后指针。“0”未分配,“1”已分配。
基于顺序搜索的动态分区分配算法
(1)首次适应算法(first fit,FF)
优点:倾向于优先利用内存中低址部分的空闲分区,从而保留了高址部分的大空闲区。
缺点:低址部分不断被划分,会留下许多难以利用的、很小的空闲分区,称为碎片。而每次查找又都是从低址部分开始的,这无疑又会增加查找可用空闲分区时的开销。
(2)循环首次适应算法(next fit,NF)
是FF的改进,从上次找到的空闲分区的下一个空闲分区开始查找。
优点:该算法能使空闲分区分布得更均匀,从而减少了查找空闲分区时的开销。
缺点:会缺乏大的空闲分区。
(3)最佳适应算法(best fit,BF)
空闲分区按其从小到大的顺序链接。顺链找到第一个满足要求的空闲分区。
缺点:会留下许多难以利用的碎片。
(4)最坏适应算法(worst fit,WF)
动态可重定位分区分配
1.紧凑:通过移动内存中作业的位置,把原来多个分散的小分区拼接成一个大分区。
- 每次“紧凑”后,都必须对移动了的程序或数据进行重定位。
- 大大影响系统的效率。
2.动态重定位
- 程序在执行时,真正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成的。
- 地址变换过程是在程序执行期间,随着对每条指令或数据的访问自动进行的,故称为动态重定位。
对换
对换是指把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或进程所需要的程序和数据换入内存。
- 整体对换:以整个进程为单位。
- 页面(分段)对换:以进程的一个“页面”或“分段”为单位。
离散内存分配方法
- 分页存储管理方式:将用户程序的地址空间分为若干个固定大小的区域,称为“页”或“页面”。典型的页面大小为1KB。相应的,也将内存你空间分为若干个物理块或页框,页和块的大小相同。这样可将用户程序的任一页放入任一物理块中,实现了离散分配。
- 分段存储管理方式:把用户程序的地址空间分为若干个大小不同的段,每段可定义一组相对完整的信息。在存储分配时,以段为单位,这些段在内存中可以不相邻接,所以也同样实现了离散分配。
- 段页式存储管理方式:这是分页和分段两种存储管理方式相结合的产物,同时具有两者的优点,应用较广泛。
分页
页面和物理块
地址结构
页表
地址变换机构
基本的地址变换机构
具有快表的地址变换机构
两级和多级页表
1.逻辑地址结构
2.两级地址变换机构
3.多级页表
分段存储管理方式
分段引入
1.方便编程:用户把自己的作业按照逻辑关系划分为若干段。
2.信息共享:在实现对程序和数据的共享时,是以信息的逻辑单位(段)为基础的。
3.信息保护:经常以一个过程、函数、或文件为基本单位进行保护的。
4.动态增长
5.动态链接:在程序运行时,当需要调用某个目标程序时,才将该段(目标程序)调入内存并进行链接。动态链接要求的是以目标程序(段)作为链接的基本单位。
分段
段表
地址变换机构
分页和分段的主要区别
分页和分段系统都采用离散分配方式,且都是通过地址映射机构实现地址变换。
- 页是信息的物理单位。采用分页存储管理方式是为实现离散分配方式,以消减内存的外零头,提高内存的利用率。或者说,分页仅仅只是系统管理上的需要,完全是系统的行为,对用户是不可见的。
- 段是信息的逻辑单位。它通常包含的是一组意义相对完整的信息。分段的目的主要在于能更好的满足用户需要。
- 页的大小固定且由系统决定。在采用分页存储管理方式的的系统中,在硬件结构上,就把用户程序的逻辑地址划分为页号和页内地址两部分,也就是说是由硬件实现的,因而在每个系统中只能有一种大小的页面。
- 而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时,根据信息的性质来划分。
- 分页的用户程序地址空间是一维的。分页完全是系统的行为,故在分页系统中,用户程序的地址是属于单一的线性地址空间,程序员只需利用一个记忆符即可表示一个地址。
- 而分段是用户的行为,故在分段系统中,用户程序的地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
段页式存储管理方式
基本原理
地址变换过程
虚拟内存分配方法
局部性原理
虚拟内存的概念
所谓虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统。
其逻辑容量由内存和外存容量之和所决定,其运行速度接近于内存速度,而每位的成本却又接近于外存。
特点:
- 多次性:是指一个作业中的程序和数据无需在作业运行时一次性地全部装入内存,而是允许被分成多次调入内存中运行,即只需将当前要运行的那部分程序和数据装入内存即可开始运行。
- 对换性:在进程运行期间,允许将那些暂不用的代码和数据从内存调至外存的对换区(换出),待以后需要时再将它们从外存调入至内存(换进)。
- 虚拟性:虚拟性是指能够从逻辑上扩充内存容量,使用户所看到的的内存容量远大于实际内存容量。
虚拟存储器的实现方法
分页请求系统
请求分段系统
页面置换算法
最佳置换算法和先进先出置换算法
1.最佳(Optimal)置换算法(Optimal)
其所选择的的被淘汰页面将是以后永不使用的,或许是在最长(未来)时间内不再被访问的页面。
通常可以保证最低的缺页率,但是无法预知,无法实现。
2.先进先出(FIFO)页面置换算法
该算法总是淘汰最先进入内存的界面,即选择在内存中驻留时间最久的页面予以淘汰。
最近最久未使用和最少使用置换算法
1.LRU(Least Rencently Used)置换算法
2.最少使用(Least Frequently Used,LFU)置换算法
选择在最近时期使用最少的页面作为淘汰页。
Clock置换算法(LRU近似算法)
1.简单的Clock置换算法
2.改进型Clock置换算法