实验7 可变分区

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验7 可变分区管理
实验内容
内存是中央处理机能直接存取指令和数据的存储器。

能否合理而有效的使用内存,在很大程度上将影响到整个计算机系统的性能。

本实验实现内存空间的分配与回收。

实验目的
本实验主要让大家熟悉内存的各种分配和回收。

所谓分配,就是解决多道作业或多个进程如何共享内存空间的问题。

所谓回收,就是当作业运行完成时,将作业或进程所占用的内存空间归还给系统。

内存的分配与回收的实现是与内存的管理方式有关的。

通过本实验,帮助大家理解不同的存储管理方式下,如何实现内存空间的分配与回收。

实验题目采用可变式分区管理,使用首次适应算法实现内存的分配与回收
要求采用分区说明表进行实验。

提示:
(1) 可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数可以调整。

当要装入一个作业时,根据作业需要的内存量,查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若没有,则作业等待。

随着作业的装入、完成,内存空间被分割成许多大大小小的分区。

有的分区被作业占用,有的分区空闲。

例如,某时刻内存空间占用情况如图1所示。

为了说明那些分区是空闲的,可以用来装入新作业,必须要有一张空闲区说
明表,如表1所示。

其中,起始地址指出个空闲区的内存起始地址,长度指出空闲区的大小。

状态(未分配:该栏目记录的是有效空闲区) 状态(空表目:没有登记信息) 由于分区个数不定,所以空闲区说明表中应该有足够的空表目项。

否则造成溢出,无法登记。

同样,再设一个已分配表,记录作业或进程的内存占用情况。

(2) 当有一个新作业要求装入内存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需求量,这时应将空闲区一分为二。

一个分给作业,另外一个作为空闲区留在空闲区表中。

为了尽量减少由于分割造成的碎片,尽可能分配低地址部分的空闲区,将较大空闲区留在高地址端,以利于大作业的装入。

为此在空闲区表中,按空闲区首地址从低到高进行登
图1 内存空间占用情况
65K
110K
256K
0 20K
45K 10K
记。

为了便于快速查找,要不断地对表格进行紧缩,即让“空表目”项留在表的后部。

其分配框图如图2所示。

图2 首次适应算法分配框图
(3) 当一个作业执行完成时,作业所占用的分区应归还给系统。

在归还时要考虑相邻空闲区合并的问题。

作业的释放区与空闲区的邻接分以下4种情况考虑:
●释放区下邻(低地址邻接)空闲区;
●释放区上邻(高地址邻接)空闲区;
●释放区上下都与空闲区邻接;
●释放区与空闲区不邻接。

首次适应算法回收框图如图3所示。

(4) 请按首次适应算法设计内存分配和回收程序。

以表2当前使用的基础,初始化空闲区和已分配区说明表值。

设计一个作业申请队列以及作业完成后的释放顺序,实现内存的分配与回收。

把空闲区说明表的变化情况以及各作业的申请、释放情况显示或打印出来。

参考程序
#include "stdio.h"
#define N 5
struct freearea /*定义一个空闲区说明表结构,并初始化变量*/
{
int startaddress; /*空闲区始址*/
int size; /*空闲区大小*/
int state; /*空闲区状态:0表示空表目,1为可用空闲块*/ }freeblock[N]={{20,20,1},{80,50,1},{150,100,1},{300,30,0},{600,100,1}};
/*定义为作业分配主存空间的函数alloc()*/
int alloc(int applyarea) /*applyarea为作业申请量*/
{
int i,tag=0; /*tag为检查是否有满足作业需要的空闲区的标志*/
for(i=0;i<N;i++) /*检查空闲区说明表是否有满足作业要求的空闲区*/
if(freeblock[i].state==1 && freeblock[i].size>applyarea)( 为两个&)
{
freeblock[i].startaddress=freeblock[i].startaddress+applyarea;
freeblock[i].size=freeblock[i].size-applyarea;
tag=1; /*有满足条件的空闲区时,tag置为1*/
return freeblock[i].startaddress-applyarea;
}
else
if(freeblock[i].state==1 && freeblock[i].size==applyarea)
{
freeblock[i].state=0;
tag=1; /*有满足条件的空闲区时,tag置为1*/
return freeblock[i].startaddress; /*返回为作业分配的主
存地址*/
}
if(tag==0)
return -1; /*没有满足条件的空闲区,分配不成功,返回-1*/
}
/*定义主存回收函数:setfree() */
/*tag1代表释放区的高地址是否邻接一个空闲区,tag2代表释放区的高低地址是否都邻接一个空闲区,
tag3代表释放区的低地址是否邻接一个空闲区*/
void setfree()
{
int s,la,tag1=0,tag2=0,tag3=0,i,j;
printf("input free area startaddress: \n");
scanf("%d",&s); /*输入释放区的开始地址*/
printf("input free area size:\n");
scanf("%d",&la); /*输入释放区的大小*/
for(i=0;i<N;i++)
{
if(freeblock[i].startaddress==s+la && freeblock[i].state==1)
{
la=la+freeblock[i].size;
tag1=1; /*有与释放区高地址邻接的空闲区,tag=1*/
for(j=0;j<N;j++)
if(freeblock[j].startaddress+freeblock[j].size==s && freeblock[j].state==1)
{
freeblock[i].state=0;
freeblock[j].size=freeblock[j].size+la;
tag2=1; /*有与释放区上下都邻接的空闲区*/
break;
}
if(tag2==0) /*无与释放区高地址邻接的空闲区*/
{
freeblock[i].startaddress=s;
freeblock[i].size=la;
break;
}
}
}
if(tag1==0) /*无与释放区高地址邻接的空闲区,检查是否低地址有邻接空闲区*/
{
for(i=0;i<N;i++)
if(freeblock[i].startaddress+freeblock[i].size==s && freeblock[i].state==1)
{
freeblock[i].size=freeblock[i].size +la;
tag3=1; /*有与释放区的低地址邻接的空闲区*/
break;
}
if(tag3==0) /*没有与释放区的低地址邻接的空闲区*/
for(j=0;j<N;j++)
if(freeblock[j].state==0) /*找一个空表目,将释放区放入表中*/
{
freeblock[j].startaddress=s;
freeblock[j].size=la;
freeblock[j].state=1;
break;
}
}
}
/*定义对空闲区表中的空闲区调整的函数adjust()
使空闲区按始地址从小到大排列,空表目放在后面*/
void adjust()
{
int i,j;
struct freearea middata;
for(i=0;i<N;i++) /*将空闲区按始地址顺序在表中排列*/
for(j=0;j<N;j++)
if(freeblock[j].startaddress>freeblock[j+1].startaddress)
{
middata.startaddress=freeblock[j].startaddress;
middata.size=freeblock[j].size;
middata.state=freeblock[j].state;
freeblock[j].startaddress=freeblock[j+1].startaddress;
freeblock[j].size=freeblock[j+1].size;
freeblock[j].state=freeblock[j+1].state;
freeblock[j+1].startaddress=middata.startaddress;
freeblock[j+1].size=middata.size;
freeblock[j+1].state=middata.state;
}
for(i=0;i<N;i++) /*将空表目放在表后面*/
for(j=0;j<N;j++)
if(freeblock[j].state==0 && freeblock[j+1].state==1)
{
middata.startaddress=freeblock[j].startaddress;
middata.size=freeblock[j].size;
middata.state=freeblock[j].state;
freeblock[j].startaddress=freeblock[j+1].startaddress;
freeblock[j].size=freeblock[j+1].size;
freeblock[j].state=freeblock[j+1].state;
freeblock[j+1].startaddress=middata.startaddress;
freeblock[j+1].size=middata.size;
freeblock[j+1].state=middata.state;
}
}
/*定义打印空闲区说明表函数:print() */
void print()
{
int i;
printf(" |...............................................|\n");
printf(" | start size state |\n");
printf(" |...............................................|\n");
for(i=0;i<N;i++)
{
printf(" | %3d %3d %3d |\n",
freebleck[i].startaddress,freeblock[i].size,freeblock[i].state);
printf(" |...............................................|\n");
}
}
void main()
{
int applyarea,start,j;
char end;
printf("\n is there any job request memory? y or n:\n");
while((end=getchar())=='y')
{
printf("at first the free memory is this:\n");
adjust();
print();
printf("input request memory size:");
scanf("%d", &applyarea);
start=alloc(applyarea);
adjust();
printf("after allocation, the free memory is this:\n");
print();
if(start==-1)
printf("there is no fit memory, please wait\n");
else
{
printf("job's memory start address is: %d\n",start);
printf("job's size is: %d\n",applyarea);
printf("job is running. \n");
printf("job is terminated. \n");
for(j=1;j<100000;j++) /*延迟时间*/
{}
setfree();
adjust();
print();
printf(is there any job that is waiting? y or n:\n);
end=getchar();
}
}
}
回答下列问题:
1.程序能否顺利执行?如不能,有哪些错误,如何修改?
2.你输入的请求内存区的大小为多少?()
你输入的释放的内存区的首地址是多少(),大小为多少()
运行结果为:(可以截图)
3.如果input request memory size :为40,请求分配后内存空闲区表为:
4.如果input free area startaddress为40,input free area size为40:回收后
内存空闲表为:。

相关文档
最新文档