实验四 主存空间的分配和回收模拟
1. 实验目的
为了合理地分配和使用这些存储空间,当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间和使用情况,找出足够的空闲区域给申请者。当作业撤离归还主存资源时,则存储管理要收回占用的主存空间。主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助我们理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
用高级语言完成一个主存空间的分配和回收模拟程序,以加深对内存分配方式及其算法的理解。
2. 实验内容
2.1 模拟包括3部分:
1)实现特定的内存分配算法
2)实现内存回收模拟
3)每种内存分配策略对应的碎片数统计
2.2 固定分区存储管理
假设内存容量为120KB,并且分别划分成8,16,32,64KB大小的块各一块。
一个进程所需要的内存为0到100个KB。同时假设一个进程在运行过程中所需内存的大小不变。
模拟五个进程到达请求分配与运行完回收情况,输出主存分配表.
2.3 动态分区分配存储管理
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、下次适应算法、最佳适应算法和最坏适应算法4种算法完成设计(任选两种算法)。
(1)在程序运行过程,由用户指定申请与释放。
(2)设计一个已占用分区表,以保存某时刻主存空间占用情况。
(3)设计一个空闲分区表,以保存某时刻主存空间剩余情况。
(4)用两个表的变化情况,反应各进程所需内存的申请与释放情况。
3. 实验环境
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
可以选用Turbo C作为开发环境。也可以选用Windows下的VB,CB或其他可视化环境,利用各种控件较为方便。自主选择实验环境。
3. 源代码
#include<stdio.h>
#include <stdlib.h>
#include <conio.h>
#define nil -1
#define NULL 0
#define maxisize 600 //用户的空闲区空间最大值
#define minisize 4
#define getspace(type) (type*)malloc(sizeof(type)) //分配空间
struct table{
char job; //作业标号
float address; //分区起始地址
float length; //分区长度,单位为字节
int flag; //分区表的状态位
struct table *FRlink; //前向指针
struct table *RElink; //后向指针
}*free_table=NULL,*place; //已分配分区表,空闲分区表
typedef struct table FRtable;
FRtable *init(FRtable *tb)
{
tb->FRlink=NULL;
tb->job=nil;
tb->address=0;
tb->length=2048;
tb->flag=0;
tb->RElink=NULL;
return tb;
}
void allocate(char job,float xk,int choice)
{
FRtable *tb,*link;
int k=0;float temp=600;
if (free_table->FRlink==NULL&&free_table->RElink==NULL)
{
free_table->job=job;
free_table->length=xk;
free_table->flag=1;
if (xk<maxisize)
{
tb=getspace(FRtable);
free_table->RElink=tb;
tb->FRlink=free_table;
tb->job=nil;
tb->address=0+xk;
tb->length=maxisize-xk;
tb->flag=0;
}
if (choice==2)
{
free_table->FRlink=tb;
tb->RElink=free_table;
place=tb;
}
else
{
free_table->FRlink=NULL;
if (xk<maxisize) tb->RElink=NULL;
}
k=1;
}
else
{
if (2==choice) tb=place;//采用CFF时将ta定位到上次找到的合适空间分区的下个空间分区
else tb=free_table;
while(tb!=NULL)
{
if (tb->length>=xk&&tb->flag==0)
if (tb->length-xk<=minisize)
{//当搜索到的空间大小<=xk+minisize时,将空间全部分配给作业
tb->job=job;
tb->flag=1;
place=tb->RElink;
k=1;
break;
}
else
{//当搜索到的空间大小>xk+minisize时,将空间划分,再分配给作业
link=getspace(FRtable);
link->length=tb->length-xk;
tb->job=job;
tb->length=xk;
tb->flag=1;
link->RElink=tb->RElink;
if (NULL!=tb->RElink) tb->RElink->FRlink=link;
tb->RElink=link;
link->FRlink=tb;
link->job=nil;
link->address=tb->address+xk;
link->flag=0;
place=link;
k=1;
break;
}
tb=tb->RElink;
}
}
if (0==k)
{
printf(">>空间申请失败! \n");
return;
}
}
//主存回收函数,回收作业job所占用的分区空间
void reclaim(char job,int choice)
{
int bool1=0,bool2=0;
FRtable *tb,*link;
tb=free_table;
if (2==choice) link=tb;
else link=NULL;
do
{
if (job==tb->job&&1==tb->flag) break;
tb=tb->RElink;
if (tb==link)
{
printf("\n>>抱歉,不存在作业%c! \n",job);
return;
}
}while(tb!=link);
bool1=(NULL==tb->FRlink||tb->FRlink==tb->RElink)? 1:tb->FRlink->flag;
bool2=(NULL==tb->RElink||tb->FRlink==tb->RElink)? 1:tb->RElink->flag;
if (bool1&&bool2)
{
tb->job=nil;
tb->flag=0;
}
else if ((NULL==tb->FRlink||1==tb->FRlink->flag)&&0==tb->RElink->flag)
{
link=tb->RElink;
tb->job=nil;
tb->length+=link->length;
tb->flag=0;
tb->RElink=link->RElink;
if (NULL!=link->RElink) link->RElink->FRlink=tb;
free(link);
}
else if (0==tb->FRlink->flag&&1==tb->RElink->flag)
{
link=tb->FRlink;
link->length+=tb->length;
link->RElink=tb->RElink;
tb->RElink->FRlink=link;
if (free_table==tb) free_table=link;
free(tb);
}
else if (0==tb->FRlink->flag&&0==tb->RElink->flag)
{
link=tb->FRlink;
link->length=link->length+tb->length+tb->RElink->length;
link->RElink=tb->RElink->RElink;
if (NULL!=tb->RElink->RElink) tb->RElink->RElink->FRlink=link;
if (free_table==tb) free_table=link;
free(tb);
free(tb->RElink);
}
}
//显示空间分区链表
void display(FRtable *tb,int choice)
{
// clrscr();
FRtable *temp;
if (2==choice) temp=tb;
else temp=NULL;
printf("\n\t标号\t分区首地址\t分区大小(KB)\t\n");
do
{
printf("\n\t %c\t %.2f\t %.2f\t\t %d",tb->job,tb->address,tb->length,tb->flag);
tb=tb->RElink;
}while(temp!=tb);
}
//主函数
int main()
{
int i,a,choice;
float xk;
char job;
FRtable *ta=getspace(FRtable);
free_table=init(ta);
do{
printf("\n 分区分配算法:\n\t0 - 退出(Exit)\n\t1 - 首次适应算法(FF)\n\t2 - 循环首次适应算法\n\t\n");
printf(">>请选择相应的算法(0-2):");
scanf("%d",&choice);
if (0==choice) exit(0);
}while(0>choice&&2<choice);
while(1)
{
printf("\n 菜单:\n\t0 - 退出(Exit)\n\t1 - 申请空间(Allocation)\n\t2 - 回收空间(Reclaim) \n");
printf(">>请选择你的操作(0-2):");
scanf("%d",&a);
switch(a)
{
//a=0,程序结束
case 0:exit(0);
//a=1,分配主存空间
case 1:printf(">>请输入作业标号和所需要申请的空间:");
scanf("%*c%c%f",&job,&xk);
allocate(job,xk,choice);
display(free_table,choice);
break;
//a=2,回收主存空间
case 2:printf(">>请输入你想回收的作业的相应标号:");
scanf("%*c%c",&job);
reclaim(job,choice);
display(free_table,choice);
break;
default:printf(">>ERROR:No thie choose! \n");
}
}
}
4. 截图
试验总结:
本次试验让我们了解了主存空间的分配和回收模拟,具体的运算方法。通过实验对自己的编程和cup的内部处理过程有了更好的理解