存储器管理
一、目的
本课题实验的目的是,使学生实验存储器管理系统的设计方法;加深对所学各种存储器管理方案的了解;要求采用一些常用的存储器分配算法,设计一个存储器管理模拟系统并调试运行。
二、要求及提示
1、根据范例,使用三种存储器分配算法,设计一个存储器管理模拟系统。允许进行多次的分配和释放,并可向用户反馈分配和释放情况及当前内存的情况;采用“命令菜单”选择和键盘命令输入的会话方式,根据输入请求调用分配模块,或回收模块,或内存查询模块,或最终退出系统。
2、编程实现。
3、工具:C 语言或其它高级语言
4、实验时间:3 学时
三、实验报告
1、写出存储器管理的思想。
2、画出算法流程图和设置的数据结构。
3、写出调试程序出现的问题及解决的方法。
4、打印实验报告及程序清单。
5、报告给出测试的结果。
四、范例
采用可变分区存储器管理方案的模拟系统。
1、问题描述
该模拟系统的外部特性与真实系统基本一样。存储分配算法采用首次适应法。用“拼,接”和“紧凑”技术来处理存储器碎片。
2、算法
存储分配算法采用首次适应(FF)法。根据指针 freep 查找自由链,当找到第一块可满足分配请求的空闲区时便分配之。当某空闲区被分配后的剩余空闲区空间大于规定的碎片最小容量 min 时,则形成一个较小的空闲区留在自由链中。回收时,根据 MAT 将指定分区链入自由链。若该分区有前邻或后邻空闲分区,则将他们拼接成一块加大的空闲区。当某个分配请求不能被满足,但此时系统中所有碎片总量满足分配请求的容量时,系统立即进入内存“紧凑”以消除碎片。即将各作业占用区集中下移到用户内存区的下部(高地址部分),形成一片连接的作业区,而在用户内存区的上部形成一块较大的空闲区。然后再进行分配。
本系统的主要程序模块包括:分配模块 ffallocation,回收模块 ffcolection,紧凑模块coalesce 及命令处理模块 menu。Menu 用以模拟系统的输入,采用“命令菜单”选择和键盘命令输入的会话方式,根据输入请求调用分配模块,或回收模块,或内存查询模块,或最终退出系统。
系统的主流程如图 3 所示。
3、数据结构
(1) 自由链与区头。内存空闲区采用自由链结构。链首由 freep 指向,链中各个空闲区按地址递增次序排列。初启时整个用户内存区为一个空闲区。在每个空闲区首部设置一个区头(freearca)结构。区头信息包括:
size 空闲区大小(以字节计),包括区头所占空间;
next 前向链指针,指向下一个空闲区;
back 反向链指针,指向上一个空闲区;
address 本空闲区首地址。
(2) 内存分配表 MAT。系统设置一个 MAT,每个运行作业都在 MAT 中占有一个表目,回收分区时清除相应表目。表目信息包括:
name 用户作业名;
length 作业区大小;
addr 作业区首地址;
4、程序清单
#include<stdio.h>
#include<stdlib.h>
#define TOTAL 5000
#define SETADDRESS 2000
#define MIN 100
#define MAX 10
typedef struct freearea
{ int address;
int size;
struct freearea *next;
struct freearea *back;
}*freeptr;
typedef struct mat
{ char name;
int address;
int length;
struct mat *next;
struct mat *back;
}*jobptr;
char string[10];
long totalfree;
char jobnumber;
freeptr freep;
jobptr jobp;
/********初始化**********/
int init()
{
freep=(freeptr)malloc(sizeof(struct freearea));
freep->size=TOTAL;
freep->address=SETADDRESS;
freep->next=NULL;
freep->back=NULL;
totalfree=TOTAL;
jobp=NULL;
jobnumber=0;
return(0);
}
/******分配模块*******/
int fengpei(int jl,char jn)
{
freeptr fp;
jobptr jp,jp1,jp2;
jp2=(jobptr)malloc(sizeof(struct mat));
if(totalfree<jl) return(1);
fp=freep;
while(fp!=NULL)
{
if(fp->size<jl)
fp=fp->next;
else
{
jobnumber=jobnumber+1;
totalfree=totalfree-jl;
jp2->name=jn;
jp2->length=jl;
jp2->address=freep->address;
if(jobp==NULL)
{
jp2->next=NULL;
jp2->back=NULL;
jobp=jp2;
}
else
{
jp=jobp;
while(jp!=NULL&&(jp2->address<jp->address))
{
jp1=jp;
jp=jp->next;
}
jp2->next=jp;
if(jp==NULL)
{
jp2->back=jp1;
jp1->next=jp2;
}
else
{
jp2->back=jp->back;
if(jp->back!=NULL)
jp1->next=jp2;
else
jobp=jp2;
jp->back=jp2;
}
}
if((fp->size-jl)<MIN)
{
if(fp->next!=NULL)
fp->next->back=fp->back;
if(fp->back!=NULL)
fp->back->next=fp->next;
else
freep=fp->next;
/* return();*/
}
else
{
fp->size=fp->size-jl;
fp->address=fp->address+jl;
}
return(2);
}
if(totalfree>=jl)
return(0);
}
}
/*********显示模块*********/
void xianshi()
{
jobptr jp;
/****清屏****/
if(jobnumber<=0)
printf("NO JOB!");
else
{
printf("name\t\tlength\t\taddress\n");
jp=jobp;
while(jp!=NULL)
{
printf("%c\t\t%d\t\t%d\n",jp->name,jp->length,jp->address);
jp=jp->next;
}
}
printf("\nthe total left is %d bytes:",totalfree);
}
/******回收模块********/
void huishou(char jn)
{
freeptr fp,fp1,fp2;
jobptr jp;
int f=0;
jp=jobp;
while((jp!=NULL)&&(jp->name!=jn))
jp=jp->next;
if(jp!=NULL)
{
jobnumber=jobnumber-1;
totalfree=totalfree+jp->length;
if(freep==NULL)
{
freep=(freeptr)malloc(sizeof(struct freearea));
freep->address=jp->address;
freep->size=jp->address;
freep->next=NULL;
freep->back=NULL;
}
else
{
fp=freep;
while((fp!=NULL)&&(fp->address<jp->address))
{
fp1=fp;
fp=fp->next;
}
if(fp!=NULL)
{
if((fp->next!=NULL)&&(fp->next->address=jp->address+jp->length))
f=f+1;
if((fp->back!=NULL)&&(jp->address=fp1->address+fp1->size))
f=f+2;
}
else if((jp->address)=(fp1->address+fp1->size)) f=f+2;
switch(f)
{
case 0:
{
fp2=(freeptr)malloc(sizeof(struct freearea));
fp2->address=jp->address;
fp2->size=jp->length;
fp2->next=fp;
if(fp!=NULL)
{
fp2->back=fp->back;
if(fp->back!=NULL) fp1->next=fp2;
else freep=fp2;
fp->back=fp2;
}
else
{
fp2->back=fp1;
fp1->next=fp2;
}
break;
}
case 1:
{
fp->size=fp->size+jp->length;
fp->address=jp->address;
break;
}
case 2:
fp1->size=fp1->size+jp->length; break;
case 3:
{
fp1->size=fp1->size+jp->length+fp->size;
fp1->next=fp->next;
if(fp->next!=NULL) fp->next->back=fp2;
free(fp);
break;
}
}
}
if(jp==jobp) jobp=jp->next;
if(jp->next!=NULL) jp->next->back=jp->back;
if(jp->back!=NULL) jp->back->next=jp->next;
free(jp);
}
}
/*********搬家************/
void banjia()
{
freeptr fp,fp1;
jobptr jp;
long bottom;
if(jobnumber>0)
{
jp=jobp;
bottom=TOTAL+SETADDRESS;
while(jp!=NULL)
{
jp->address=bottom-jp->length;
bottom=bottom-jp->length;
jp=jp->next;
}
fp=freep;
while(fp!=NULL)
{
fp1=fp;
fp=fp->next;
free(fp1);
}
freep=(freeptr)malloc(sizeof(freeptr));
freep->size=totalfree;
freep->address=SETADDRESS;
freep->next=NULL;
freep->back=NULL;
}
}
void mingling()
{
char name,anykey,jobname;
int length,select;
int address;
{
a1: //clrscr(); //用 system("cls"); 替换
system("cls");
printf("you can select one of the following:\n");
printf(" (1)require to be allocate\n");
printf(" (2)require to collexte the size\n");
printf(" (3)check the memory\n");
printf(" (4)quit system\n");
printf("you select is:");
scanf("%d",&select);
switch(select)
{
case 1:
if(jobnumber>=MAX)
printf("the job is too many");
else
{
printf("enter you job name\n");
scanf("%s",&name);
printf("enter your job length\n");
scanf("%10d",&length);
address=fengpei(length,name);
switch(address)
{ case 1: printf("the memory is full");break;
case 0:
{
banjia();
fengpei(length,name);
xianshi();
break;
}
case 2: xianshi(); break;
/*****else xianshi();*****/
}
break;
}
case 2:
{
printf("enter the name of the job\n");
printf("you select is:");
jobname=getchar(); //清除之前滞留在缓冲区的回车符“\n”
jobname=getchar();
// scanf("%c",&jobname);
// printf("%c",jobname);
huishou(jobname);
xianshi();
break;
}
case 3: xianshi(); break;
case 4: goto a2;
}
printf("\npress enter to return menu\n");
anykey=getchar();
anykey=getchar();
/* scanf("%c",anykey); */
goto a1;
a2: printf("you have exit the system!");
}
}
int main()
{
init();
mingling();
return 0;
}