首次适应算法和最佳适应算法

      今天就自己的课设题目来介绍一下动态分区分配里面的首次适应算法和最佳适应算法。
      首先大家要了解什么是动态分区分配?所谓动态分区分配 就是在处理作业的过程中,建立分区,依用户请求的大小分配分区。在分区回收的过程中会涉及一个空间利用效率相关的放置策略,即选择空闲区的策略。
常用的放置策略——首次匹配(首次适应算法)
                           最佳匹配(最佳适应算法)
                           最坏匹配(最坏适应算法)
      一、首次适应算法(First Fit):该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链    中。
     特点: 该算法倾向于使用内存中低地址部分的空闲区,在高地址部分的空闲区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。
     缺点:低地址部分不断被划分,留下许多难以利用、很小的空闲区,而每次查找又都从低地址部分开始,会增加查找的开销。
       二、最佳适应算法(Best Fit):该算法总是把既能满足要求,又是最小的空闲分区分配给作业。为了加速查找,该算法要求将所有的空闲区按其大小排序后,以递增顺序形成一个空白链。这样每次找到的第一个满足要求的空闲区,必然是最优的。孤立地看,该算法似乎是最优的,但事实上并不一定。因为每次分配后剩余的空间一定是最小的,在存储器中将留下许多难以利用的小空闲区。同时每次分配后必须重新排序,这也带来了一定的开销。
     特点:每次分配给文件的都是最合适该文件大小的分区。
     缺点:内存中留下许多难以利用的小的空闲区。
      三、最坏适应算法(Worst Fit):最坏适应算法是将输入的作业放置到主存中与它所需大小差距最大的空闲区中。空闲区大小由大到小排序。
      特点:尽可能地利用存储器中大的空闲区。
      缺点:绝大多数时候都会造成资源的严重浪费甚至是完全无法实现分配。
      关于三种放置策略的讨论:首次适应算法、最佳适应算法、最坏适应算法的队列结构。     


      介绍了这么多,下面具体说说代码实现空闲区动态分配回收的具体过程。

      首先是一些宏的定义:

#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1    //完成
#define ERROR 0 //出错

#define MAX_length 640  //定义最大主存信息640KB

      六大函数:

①status Alloc(int):内存分配函数,对于选择的首次适应算法或者是最佳适应算法判断分配完成状态,说明是否实现分配或者是分配错误。

②Status free(int):内存回收函数,主要涉及合并内存的三种情况

该空闲块与前面的空闲块相连的主存回收,表示为:

if (p->prior != block_first && p->prior->data.state == Free)

{
p->prior->data.size += p->data.size;//空间扩充,合并为一个
p->prior->next = p->next;//去掉原来被合并的p
p->next->prior = p->prior;
p = p->prior;

}

该空闲块与后面的空闲块相连,表示为:

if (p->next != block_last && p->next->data.state == Free)
{
p->data.size += p->next->data.size;//空间扩充,合并为一个
p->next->next->prior = p;
p->next = p->next->next;
}

该空闲块与该空闲块与与最后的空闲块相连,表示为:

if (p->next == block_last && p->next->data.state == Free)

{
p->data.size += p->next->data.size;
p->next = NULL;

}

③Status First_fit(int):首次适应算法,只需要将地址由小到大排列好,从头指针开始遍历,逐个检验,找到第一个空间>=所申请的空间时,给予分配。
temp->prior = p->prior;
temp->next = p;
temp->data.address = p->data.address;
p->prior->next = temp;
p->prior = temp;
p->data.address = temp->data.address + temp->data.size;
p->data.size -= request;
④Status Best_fit(int):对由小到大的空闲区排列的空闲区,与所申请的内存大小相比,取两者差最小的给予分配,插入。

初始化最小空间和最佳位置,用ch来记录最小位置。

⑤void show():查看分配。

⑥Status Initblock():开创带头结点的内存空间链表。

      完整的代码请下载:

链接:https://pan.baidu.com/s/1D9nTBGEqPKlgrH_rlceiYA 密码:v4di

      对最终的结果进行测试:

假设初始状态下,可用的内存空间为640KB,并有下列的请求序列: 

•作业1申请130KB •作业2申请60KB。 
•作业3申请100KB •作业2释放60KB。 
•作业4申请200KB •作业3释放100KB。
•作业1释放130KB •作业5申请140KB。 

•作业6申请60KB •作业7申请50KB •作业6释放60KB。

首次适应算法:

最佳适应算法:

验证无误!

展开阅读全文

没有更多推荐了,返回首页