张蒙用首次适应算法模拟内存的分配和回收.docx
- 文档编号:23438005
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:18
- 大小:407.81KB
张蒙用首次适应算法模拟内存的分配和回收.docx
《张蒙用首次适应算法模拟内存的分配和回收.docx》由会员分享,可在线阅读,更多相关《张蒙用首次适应算法模拟内存的分配和回收.docx(18页珍藏版)》请在冰豆网上搜索。
张蒙用首次适应算法模拟内存的分配和回收
采用首次适应算法实现主存的分配和回收
一、目的
在计算机系统中,为了提高内存区的利用率,必须给电脑内存区进行合理的分配。
本实验通过对内存区分配方法首次适应算法的使用,来了解内存分配的模式。
在熟练掌握计算机分区存储管理方式的原理的基础上,编程模拟实现操作系统的可变分区存储管理的功能,一方面加深对原理的理解,另一方面提高根据已有原理通过编程解决实际问题的能力,为进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。
二、实验内容与数据结构:
(1)可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区的个数是可以调整的。
当需要装入一个作业时,根据作业需要的贮存量,查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若无,则作业等待。
随着作业的装入、完成,主存空间被分割成许多大大小小的分区。
有的分区被分配作业占用,有的分区空闲,例如,某时刻主存空间占用情况如图所示:
为了说明哪些分区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,如下图所示。
(2)当有一个新作业要求装入贮存时,必须查空闲区说明表,从中找出一个足够大的空闲区。
有时找到的空闲区可能大于作业的需求量,这时应将空闲区一分为二。
一个分给作业,另一个仍作为空闲区留在空闲区表中。
为了尽量减少由于分割造成的碎片,尽可能分配地地址部分的空闲区,将较大的空闲区留在高地址端,以利于大作业的装入。
为此在空闲区表中,按空闲区首地址从低到高进行登记。
(3)当一个作业执行完成时,作业所占用的分区应归还给系统。
在归还时,要考虑相邻空间区合并问题。
作业的释放区与空闲区的邻接分以下4种情况考虑:
A、释放区下邻空闲区;
B、释放区上邻空闲区;
C、释放区上下都与空闲区邻接;
D、释放区上邻空闲区不邻接;
一、实验要求
1.内存大小初始化
2.可以对内存区进行动态分配,采用首次适应算法来实现
3.可以对已分配的内存块进行回收,并合并相邻的空闲内存块。
二、实验内容
把一个作业装入内存,按照首次适应算法对内存区进行分配,作业结束,回收已分配给该作业的内存块,并合并相邻的空闲内存块。
三、实验结果
运行效果:
1.初始化内存区大小,并添加作业,选择1添加作业
2.当作业大小超过存储块大小时,分配失败。
3.选择3,可查看内存分配情况
4.选择2回收内存
5.选择1添加新作业
6.回收C作业,相邻的空闲内存块合并。
五、程序流程图:
六、实验源代码:
//FirstFit.cpp:
可变分区用首次适应算法来模拟内存回收
#include
#include
intMAX_SEGMENT=10;//最大碎片值
structPartition//分区表目
{
intPar_Size;//分区大小
intPar_No;//分区序号或者名字
intAddr;//分区地址
intIsUse;//分区使用情况,0表示空闲,1表示使用
Partition*pri;//前向指针
Partition*next;//后向指针
};
Partition*Int()//函数,返回Partition类型指针
{//初始化空闲分区表
Partition*list,*H,*H1;
list=(structPartition*)malloc(sizeof(structPartition));
list->next=NULL;
H=list;
if(!
list)
{
printf("\n错误,内存初始化分配失败!
程序结束");
exit
(1);
}
H1=(structPartition*)malloc(sizeof(structPartition));
printf("请预先输入分区总大小(以KB为单位):
");
scanf("%d",&H1->Par_Size);
H1->Addr=0;
H1->Par_No=0;
H1->IsUse=0;
H1->pri=H;
H1->next=NULL;
H->next=H1;////list--->H1
returnlist;
}
Partition*InitFP()
{//初始化已分配分区表
Partition*FP,*F,*H;
inti;
FP=(structPartition*)malloc(sizeof(structPartition));
FP->next=NULL;
H=FP;
for(i=0;i<10;i++)//已分配区先暂定分配十个表目
{
F=(structPartition*)malloc(sizeof(structPartition));
if(!
F)
{
printf("\n错误,内存分配失败!
程序结束");
exit
(1);
}
F->Par_Size=0;
F->Addr=0;
F->Par_No=0;
F->IsUse=0;
F->next=NULL;
H->next=F;
F->pri=H;
H=H->next;
}
returnFP;
}
Partition*New_Process(Partition*list,Partition*FP)
{//为新的进程分配资源
Partition*H,*P,*H1;
intSize,Name,L;
H=list;
H1=FP->next;
H=H->next;
printf("请输入新作业的名称和大小(整数):
");
scanf("%d%d",&Name,&Size);
while(H)
{
if(!
H)//表目已查完,无法分配
{
printf("\n已无空闲分区,本次无法分配!
");
returnlist;
}
else{
if(H->IsUse==0)//空表目
//if(H->Par_Size>=Size)//大小满足,空闲分区大小》要分配的大小
if(H->Par_Size>=Size)//大小满足,
{
booltemp=false;
if((H->Par_Size-Size)<=MAX_SEGMENT){//空闲分区大小-要分配的大小<碎片值,会产生碎片,将整块内存大小分配出去,
Size=H->Par_Size;//分配的大小为整块内存
temp=true;//会产生碎片
}
//其他情况就分配大小为请求大小,不会产生碎片,
L=H->Addr;//保存空闲分地址
if(temp){
printf("该次内存分配会产生碎片,将整块内存大小%d分配出去!
",Size);
}else{
printf("该次内存分配不会产生碎片");
}
break;
}
}
H=H->next;//否则,继续往下查找
}
if(H)
{
if(H->Par_Size>Size)//大小满足,空闲分区大小》要分配的大小
{
P=(structPartition*)malloc(sizeof(structPartition));//分配新的表目,处理一条数据,分配一次内存
P->IsUse=1;
P->Addr=L;//指向空闲分区地址
P->next=H;//修改指针
H->pri->next=P;
P->pri=H->pri;
H->pri=P;
P->Par_Size=Size;//分配大小为要请求分配的大小
P->Par_No=Name;//名称
H->Par_Size-=Size;//修改空闲分区,H所指区块大小减Size
H->Addr+=Size;//H所指区块地址加Size
}else
{
H->IsUse=1;//大小相等的,把当前表项设置空表目
}
while(H1)
{
if(H1->IsUse==0)
{
H1->Par_No=Name;
H1->Par_Size=Size;
H1->Addr=L;//保存已分配地址
H1->IsUse=1;//在已分配表中设置为已分配
break;
}
H1=H1->next;
}
}else
printf("所申请资源已大过系统所拥有的,请重新输入!
\n");
returnlist;
}
Partition*Reclaim(Partition*list,Partition*FP)
{//结束作业,资源回收,No为作业名,回收内存
Partition*H1,*H2,*H3,*HF;//H1为释放区,H2为后分区,H3为前分区
intNo;//作业名
H1=list;
HF=FP;//可有可无?
H1=H1->next;
HF=FP->next;
printf("请输入您想结束的作业名:
");
scanf("%D",&No);
while(HF)//对已分配表进行操作
{
if(HF->Par_No==No)
{
HF->IsUse=0;//标志为空表目
break;//这时保存着HF所指分区的信息
}
HF=HF->next;
}
if(!
HF)//如果找不到该作业,则提示出错
printf("所输入的作业名称不正确,请重新输入!
");
else{
while(H1)//对空闲表进行操作
{
if(H1->Par_No==No)
{
H1->IsUse=0;//标志为空表目
printf("内存回收成功");
break;
}
H1=H1->next;
}
H2=H1->next;//后分区
H3=H1->pri;//前分区
if(H2&&H2->IsUse==0)//后接分区为空闲
{
if(H2->next==NULL)//判断后接分区是否为尾结点
{
H1->Par_Size+=H2->Par_Size;//把H2合并到H1
H1->next=NULL;
free(H2);
printf("已回收%d大小内存",H1->Par_Size);
}else//后分区不为空闲,表示已经被使用
{
H1->Par_Size+=H2->Par_Size;
H1->next=H2->next;
H2->next->pri=H1;
free(H2);
printf("已回收%d大小内存",H1->Par_Size);
}
}
if(H3&&H3->IsUse==0)//前分区为空闲分区,则合并去前分区
{
H3->Par_Size+=H1->Par_Size;
H3->next=H1->next;
if(H1->next!
=NULL)//若H1为尾结点
H1->next->pri=H3;
free(H1);
printf("已回收%d大小内存",H1->Par_Size);
}
}
returnlist;
}
voidPrint(Partition*list,Partition*FP)
{//输出已分配分区和空闲分区
Partition*H1,*H2;
H1=list->next;
H2=FP;
H2=H2->next;
printf("****************已分配分区表*******************\n");
printf("分区序号大小始址状态\n");
while(H2)
{
printf("%d%d%d",H2->Par_No,H2->Par_Size,H2->Addr);
if(H2->IsUse==1)
printf("已分配\n");
else
printf("空表目\n");
H2=H2->next;
}
printf("**************************************************\n");
printf("****************总的空闲分区表*******************\n");
printf("分区序号大小始址状态\n");
while(H1)
{
printf("%d%d%d",H1->Par_No,H1->Par_Size,H1->Addr);
if(H1->IsUse==1)
printf("已分配\n");
else
printf("空表目\n");
H1=H1->next;
}
printf("**************************************************\n");
}
voidMain_Print(Partition*list,Partition*FP)
{//主入口函数,进行菜单选择
intop;
while
(1)
{
printf("\n主菜单\n");
printf("1.申请新的作业,分配内存\n");
printf("2.结束作业,回收内存\n");
printf("3.查看内存表\n");
printf("4.退出系统\n");
printf("\n请选择:
");
scanf("%d",&op);
switch(op)//根据输入,选择分支方向
{
case1:
New_Process(list,FP);
break;
case2:
Reclaim(list,FP);
break;
case3:
Print(list,FP);
break;
case4:
break;
default:
printf("\n选择错误,请重新选择!
");
break;
}
if(op==4)
break;//退出循环
}
}
voidmain()
{//主函数入口
structPartition*list,*FP;
list=Int();
FP=InitFP();
Main_Print(list,FP);
}
七、实验结果图示:
四、实验总结
通过此次的实验,让我对内存分配中首次适应算法更加熟悉,通过编程模拟实现操作系统的可变分区存储管理的功能,一方面加深对原理的理解,另一方面提高根据已有原理通过编程解决实际问题的能力,为进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 张蒙用 首次 适应 算法 模拟 内存 分配 回收