存储器管理的基本概念

来源:互联网 发布:mysql slow.log 删除 编辑:程序博客网 时间:2024/06/05 04:05

 逻辑地址:用户编程时所使用的地址。又称相对地址、虚地址。

  地址空间:逻辑地址的集合。

  物理地址:内存中的地址。又称绝对地址、实地址。

  主存空间:物理地址的集合。

物理地址=逻辑基址*16+偏移量

 

  地址变换:将逻辑地址转换为物理地址。又称地址映射、重定位。

  地址变换分为两类:

  静态地址变换

  动态地址变换

  静态地址变换:又称静态地址重定位,地址变换在程序装入时一次完成,以后不再改变。

  特点:不需硬件支持,但程序运行时不能在内存移动,程序需要连续存储空间,难以共享。

  静态地址变换示意图

  动态地址变换:又称动态重定位,在程序执行过程中,每次访问内存之前将要访问程序地址转换成内存地址。

  特点:需要硬件支持,不需连续空间,可以实现虚拟存储。

  动态地址变换示意图

  7.2 分区存储管理

  分区存储管理是多道程序系统中采用的一种最简单的方法。它把系统的内存划分为若干大小不等的区域,操作系统占一个区域,其他区域由并发进程共享,每个进程占一个区域。

  分区存储管理分为:

  固定分区

  动态分区

  1. 固定分区存储管理

  固定分区存储管理方法将内存空间划分为若干个固定大小的分区,每个分区中可以装入一道程序。分区的位置及大小在运行期间不能改变。

  为了便于管理内存,系统需要建立一张分区使用表,其中记录系统中的分区数目、分区大小、分区起始地址及状态。

  分区使用表例

  固定分区的内存分配

  分区分配:当有用户程序要装入时,由内存分配程序检索分区使用表,从中找出一个能满足要求的空闲分区分配给该程序,然后修改分区说明表中相应表项的状态;若找不到大小足够的分区,则拒绝分配内存。

  分区回收:当程序执行完毕不再需要内存资源时,释放程序占用的分区,管理程序只需将对应分区的状态置为未分配即可。

  特点:最早的多道程序存储管理方式,不能充分利用内存,存在内存碎片。

关于动态分配方案的分析: 
        通常我们将已分配给用户是用的一段连续的内存空间称为“占用块”,将未分配给任何用户的一段连续的内存空间称为“可利用空间块”或者“空闲块”,我们在这里的描述将使用“占用块”和“空闲块”这两个概念。 
        整个内存区在没有任何用户进入和运行的情况下只有一个空闲块,即整个可供用户“请求”使用的用户内存区域。随着不断的有用户请求进入系统,并依次获得系统为其分配的内存,使得整个内存区域逐渐被分割成两大部分:低地址区域包含若干占用块;高低址区域是空闲内存区域。经过一段时间后,有的用户运行结束,它们所占用的内存区释放后转变为一个个空闲块,这就使整个内存区域呈现出占用块和空闲块交错相隔的状态。而此时,如果再有新的用户“请求”到达,那么,系统如何为这个“请求”进行内存分配呢? 
        在肯定动态存储管理的前提下,我们可以采取两种方案解决这个问题,一种解决方案是系统继续把高地址的空闲块分配给用户,而不理会低地址区域是否有结束执行的用户释放的内存块,直到剩余的高地址区域的空闲块不能满足新的用户“请求”,分配操作无法再进行下去时,才去回收结束执行的用户释放的内存块,并重新组织内存,进而完成内存分配。另一种解决方案是一旦有用户释放内存,就将这块内存回收,并重新组织内存。每当有新的用户“请求”到达,系统都从低地址处开始为其找出一个合适的空闲块予以分配。 
        后面我们只讨论第二种方案,这种方案的实现要求系统建立一张记录所有空闲块的“可利用空间表”,其形式不拘,可以是“目录表”,也可以采用“链表”的形式。 

  2. 动态分区存储管理

  动态分区存储管理又称为可变分区存储管理,这种存储管理方法的实现思想是根据作业大小动态地建立分区,并使分区的大小正好适应作业的需要。因此系统中分区的大小是可变的,分区的数目也是可变的。

  动态分区中的数据结构

  在动态分区中常用的数据结构有:

  空闲分区表。用一个空闲分区表来登记系统中的空闲分区。其表项类似于固定分区。

  空闲分区链。将内存中的空闲分区以链表方式链接起来,构成空闲分区链。

  空闲分区表示意图

  空闲分区链示意图

  分区分配算法

目前常用的分区分配算法有以下几种:

  首次适应算法

  循环首次适应算法

  最佳适应算法

  最坏适应算法

  首次适应算法

  首次适应算法又称最先适应算法,该算法要求空闲分区按地址递增的次序排列。

首次适应算法分配时从表头指针开始查找可利用空间表,将找到的第一个大小不小于“请求”的空闲块的一部分分配给用户。可利用空间表本身既不按节点的初始地址有序,也不按节点的大小有序。用户释放内存,回收时只是将空闲块插入在链表的表头即可,此算法比较节省时间。

  在进行内存分配时,从空闲分区表(或空闲分区链)首开始顺序查找,直到找到第一个能满足其大小要求的空闲分区为止。

  然后,再按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍然留在空闲分区表(或空闲分区链)中。

  首次适应算法的特点

  特点:优先利用内存低地址端,高地址端有大空闲区,但低地址端有许多小空闲分区时会增加查找开销。

  循环首次适应算法

  循环首次适应算法又称下次适应算法,它是首次适应算法的变形。

该算法是首次适应算法的变种。在分配内存空间时,不再每次从表头(链首)开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。

  该算法在为进程分配内存空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足其大小要求的空闲分区为止。

  然后,再按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍然留在空闲分区表(或空闲分区链)中。

  循环首次适应算法的特点

  特点:使存储空间的利用更加均衡,但会使系统缺乏大的空闲分区。

  最佳适应算法

  最佳适应算法要求空闲分区按容量大小递增的次序排列。

最佳适应算法将可利用空间表中一个大小不小于“请求”且最接近“请求”的空闲块的一部分分配给用户。分配与回收都需要对可利用空间表从头至尾查询一遍。为了避免每次分配都要查询整个链表,通常要求节点从大到小排序,由此只需找到第一个足够大的空闲块即可予以分配。但回收时,必须把回收的空闲块放置在符合大小顺序关系的链表位置。在分配时容易产生太小而无法利用的内存碎片,同时这种做法也保留了那些很大的内存块以备响应将来发生的内存量较大的用户“请求”,从而使整个链表逐渐趋向于节点大小差别甚远的状态。这种分配算法适合请求分配内存大小范围较广的系统,此算法比较费时间。 

  在进行内存分配时,从空闲分区表(或空闲分区链)首开始顺序查找,直到找到第一个能满足其大小要求的空闲分区为止。

  如果该空闲分区大于作业的大小,则从该分区中划出一块内存空间分配给请求者,将剩余空闲区仍然留在空闲分区表(或空闲分区链)中。

  最佳适应算法的特点

  按最佳适应算法为作业分配内存,就能把既满足作业要求又与作业大小最接近的空闲分区分配给作业。

  特点:保留了大的空闲区。但分割后的剩余空闲区很小。

  最坏适应算法

  最坏适应算法要求空闲分区按容量大小递减的次序排列。

最差适应算法将可利用空间表中一个大小不小于“请求”且是链表中最大的空闲块的一部分分配给用户。要求节点从大到小排序。分配时不需查询,回收时要查询,以便插入到适当位置。这种算法将使链表的节点大小逐渐趋于均匀,适合请求分配内存大小范围较窄的系统,此算法最费时间。 

  在进行内存分配时,先检查空闲分区表(或空闲分区链)中的第一个空闲分区,若第一个空闲分区小于作业要求的大小,则分配失败;

  否则从该空闲分区中划出与作业大小相等的一块内存空间分配给请求者,余下的空闲分区仍然留在空闲分区表(或空闲分区链)中。

  最坏适应算法的特点

  特点:剩下的空闲区比较小,但当大作业到来时,其存储空间的申请往往得不到满足。

  如何衡量分配算法的好坏

  对于某一个作业序列来说,若某种分配算法能将该作业序列中所有作业安置完毕,则称该分配算法对这一作业序列合适,否则称为不合适。

0 0