内存分配首次适应算法.docx
《内存分配首次适应算法.docx》由会员分享,可在线阅读,更多相关《内存分配首次适应算法.docx(14页珍藏版)》请在冰豆网上搜索。
内存分配首次适应算法
一、实验名称:
存分配与回收
二、实验容:
用首次适应算法实现存储空间的分配,回收作业所占用的存储空间。
三、实验目的:
一个好的计算机系统不仅要有足够的存储容量,较高的存取速度和稳定可靠的存储器,而且能够合理的分配和使用这些主存空间。
当用户提出申请主存空间的要求时,存储管理能够按照一定的策略分析主存的使用情况,找出足够的空间分配给申请者;当作业运行完毕,存储管理要回收作业占用的主存空间。
本实验实现在可变分区存储管理方式下,采用最先适应算法对主存空间进展分配和回收,以加深了解操作系统的存储管理功能。
四、实验过程:
a)根本思想
空闲分区链以地址递增的次序连接。
在分配存时,从链首开始顺序查找,直至找到一个大小能够满足要求的空闲分区为止;然后再按照作业大小,从该分区中划出一块存空间分配给请求者,余下的空闲分区仍然留在空闲链中。
假如从链首直至链尾都不能找到一个能满足要求的分区,如此此次存分配失败。
b)主要数据结构
typedefstructFreeLink{//空闲链
structFreeLink*prior;
charname;
intstart;
intsize;
boolflag;
structFreeLink*next;
}*ptr,*head;
headtop;
ptrp;
c)存分配算法
当有进程要求分配主存时,依据首次适应算法从链头开始,延链查找一个足以容纳该进程的空闲区。
假如这个分区比拟大,如此一分为二,一局部分配给进程,另一局部作为空闲区仍留在链中的当前位置,修改它的上一个空闲区的前向指针值为再加上分配给进程的分区大小,下一个空闲区的后向指针值为再加上分配给进程的分区大小,使链保持完整。
假如这个分区的大小正好等于进程的大小,该分区全局部配给进程,并将该空闲区从链中摘除〔即修改下一个空闲区的后向指针=该空闲区后向指针,上一个空闲区的前向指针=该空闲区的前向指针〕。
再在已分配区表中找一个空表目,登记刚刚分配的存始址、长度和进程号。
d)存的回收
当进程运行完成,释放存时,通过输入进程号,来回收进程占用的分区。
在回收时,释放区与空闲区相邻接的情况要考虑4种情况:
⊙释放区下邻空闲区
⊙释放区上邻空闲区
⊙释放区与上下空闲区均相邻
⊙释放区与上下空闲区均不相邻
e)程序流程图
※空闲链的首次适应算法分配流程图
※空闲链的首次适应算法回收流程图
f〕截屏
五、源代码
#include
#include
#include
usingnamespacestd;
typedefstructFreeLink{//定义空闲链
structFreeLink*prior;
charname;
intstart;
intsize;
boolflag;
structFreeLink*next;
}*ptr,*head;
headtop;
ptrp;
voidprint(){//将存分配情况打印到屏幕上
p=top;
cout<<"************************存分配情况表************************"<cout<<"区号\t\t"<<"起始位置\t"<<"区间长度\t"<<"区间状态\t"<do{
cout<name<<"\t\t"<start<<"\t\t"<size<<"\t\t";
if(p->flag==false)//flag为false,明确该分区空闲
{
cout<<"空闲"<}
else
{
cout<<"已占用"<}
p=p->next;
}
while(p!
=NULL);
}
voidclear(){//完毕操作时清空“存〞以备其他操作
do{
p=top;
top=top->next;
free(p);
}
while(top!
=NULL);
cout<<"存已清空!
";
}
voidhebing(ptr&p){//假如被操作的存有相邻空闲区如此将空闲区拼接合并
intx;
if(p->prior->flag==false&&p->next->flag==false)x=1;//释放区与上下空闲区均相邻
if((p->prior->flag==false&&p->next->flag==true)||(p->prior->flag==false&&p->next==NULL))x=2;//释放区下邻空闲区
if((p->prior->flag==true&&p->next->flag==false)||(p->prior==NULL&&p->next->flag==false))x=3;//释放区上邻空闲区
if((p->prior->flag==true&&p->next->flag==true)||(p->prior==NULL&&p->next->flag==true)||(p->prior->flag==true&&p->next==NULL))x=4;//释放区与上下空闲区均不相邻
switch(x){
case1:
p->next->prior=p->prior;
p->prior->next=p->next;
p->prior->size=p->prior->size+p->size+p->next->size;
p->prior->next=p->next->next;
if(p->next->next!
=NULL)
p->next->next->prior=p->next->prior;
free(p->next);//释放
free(p);
break;
case2:
if(p->next==NULL)//p为最后一个分区
{
p->prior->next=p->next;
}
else{
p->next->prior=p->prior;
p->prior->next=p->next;
}
p->prior->size=p->prior->size+p->size;
free(p);
break;
case3:
if(p->prior==NULL)//p为第一个分区
{
top=p->next;
p->next->prior=NULL;
p->next->start=p->start;
p->next->size=p->next->size+p->size;
}
else{
p->next->prior=p->prior;
p->prior->next=p->next;
p->next->start=p->start;
p->next->size=p->next->size+p->size;
}
free(p);
break;
case4:
p->name='*';//将释放区移至链首并标记为未被占用
p->flag=false;
break;
}
}
voidallocate(ptr&p){//最先适应法的存分配函数
FreeLink*fl=(FreeLink*)malloc(sizeof(FreeLink));
cout<<"请输入要分配存的进程号:
";
cin>>fl->name;
cout<<"请输入要分配存的大小:
";
cin>>fl->size;
fl->flag=true;
do{
if(p->flag==false&&p->size>fl->size){
fl->start=p->start;
p->start=fl->start+fl->size;
p->size=p->size-fl->size;
fl->next=p;
fl->prior=p->prior;
p->prior->next=fl;
p->prior=fl;
gotoa;
}
if(p->flag==false&&p->size==fl->size){
p->flag=fl->flag;
p->name=fl->name;
free(fl);
gotoa;
}
p=p->next;
}while(p!
=NULL);
cout<<"存过小,分配失败!
"<gotob;
a:
cout<<"分配成功!
"<b:
;//啥也不做
}
voidhuishou(ptr&p){//存回收函数
charn='';
cout<<"请输入要回收的存对应的进程号:
";
cin>>n;
do{
if(p->flag==true&&p->name==n)
{
hebing(p);
gotoc;
}
p=p->next;
}while(p!
=NULL);
cout<<"存未能分配给该进程,回收失败!
"<gotod;
c:
cout<<"存回收成功!
"<d:
;
}
intfirstfit(){//最先适应法
charchoice='';
print();
ptrpcb=(FreeLink*)malloc(sizeof(FreeLink));
pcb->next=top;
pcb->prior=top->prior;
top->prior=pcb;
pcb->start=top->start;
cout<<"请输入要为系统分配的存块号:
";
cin>>pcb->name;
cout<<"请输入要分配存的大小:
";
gotof;
e:
cout<<"超过存最大容量,请重新输入要分配存的大小:
";
f:
cin>>pcb->size;
if(pcb->size>256)
gotoe;
top->size=top->size-pcb->size;
top=pcb;
top->flag=true;
top->next->start+=top->size;
print();
while(true){
do{
p=top->next;
cout<<"请从如下选项中进展选择:
"<cout<<"1.分配存"<cout<<"2.回收存"<cout<<"3.完毕操作"<cout<<"请输入你的选择:
";
cin>>choice;
}while(choice!
='1'&&choice!
='2'&&choice!
='3');
switch(choice){
case'1':
allocate(p);print();break;
case'2':
huishou(p);print();break;
case'3':
clear();return0;break;
}
}
}
intmain(){//主函数
ptrfree=(FreeLink*)malloc(sizeof(FreeLink));
top=free;
top->name='*';
top->start=0;
top->size=256;
top->flag=false;
top->prior=NULL;
top->next=NULL;
cout<cout<<"************************首次适应算法************************"<cout<firstfit();
}
六、实验小结
通过本实验,深刻地理解到了利用可变分区,采用首次适应算法为作业分配存的过程。
该算法倾向于优先利用存中低址局部的空闲分区,从而保存了高址局部的大空闲区。
这给为以后的作业分配大的存空间创造了条件。
其缺点是地低址局部不断被划分,会留下很多难以利用的,很小的空闲区,而每次查找又都是从低地址局部开始,这无疑会增加查找可用的空闲区时的开销。