a[i].size=a[i].size-size;//当前内存分配大小给作业
if(a[i+1]==null){//当下一块内存还没有使用时
a[i+1]=newNode1(size+a[i].start,size,true,jobNo);//使用该内存
}
else{//当下一块内存已被使用,那么继续寻找一块还没被使用的内存
for(intj=i+1;jif(a[j]==null){
a[j]=newNode1(size+a[j-1].start,size,true,jobNo);
break;//当找到未被使用的内存及填入内容后跳出循环
}
}
}
}
a[i].print();//打印输出当前Link中各个内存块的使用情况
}
}
}
publicvoiddelete(Node1a[],intjobNo){//删除某一个进程,当该进程被删除后,进程所在内存的状态变为false
for(inti=0;iif(a[i]!
=null){
if(a[i].jobNo==jobNo){
//a[i].size=0;
a[i].state=false;
a[i].jobNo=0;
}
if(a[i]!
=null){
a[i].print();
}
}
}
}
publicvoidback(Node1a[]){//进行状态为false的内存的回收删除内存状态为false的内存节点。
并将该节点与起始点结合
for(inti=1;iif(a[i]!
=null){
if(a[i].state==false){
a[0].size=a[0].size+a[i].size;
a[i]=null;
}
}
}
for(intj=0;jif(a[j]!
=null){
a[j].print();
}
}
}
}
//OSJob.java
publicclassJob{
publicstaticvoidmain(Stringargs[]){
Node1jobArray[]=newNode1[70];
jobArray[0]=newNode1(0,25,false,0);
Linkl=newLink();
System.out.println("--------------最初的内存--------------");
System.out.println("起始位置"+"\t"+"大小"+"\t"+"状态"+"\t"+"工作号");
jobArray[0].print();
System.out.println("-------------增加第1个作业后---------------");
System.out.println("起始位置"+"\t"+"大小"+"\t"+"状态"+"\t"+"工作号");
l.addJob(4,1,jobArray);
System.out.println("------------增加第二个作业后-----------------");
System.out.println("起始位置"+"\t"+"大小"+"\t"+"状态"+"\t"+"工作号");
l.addJob(10,2,jobArray);
System.out.println("-------------增加第三个作业后-----------------");
System.out.println("起始位置"+"\t"+"大小"+"\t"+"状态"+"\t"+"工作号");
l.addJob(10,3,jobArray);
System.out.println("-------------删除作业2后---------------------");
System.out.println("起始位置"+"\t"+"大小"+"\t"+"状态"+"\t"+"工作号");
l.delete(jobArray,2);
System.out.println("-------------添加作业4后------------------------");
System.out.println("起始位置"+"\t"+"大小"+"\t"+"状态"+"\t"+"工作号");
l.addJob(5,4,jobArray);
}
}
第二题:
#include
#include
#include
#include
#include
#include
intbitmap[8][8]={//初始化位图
{1,1,0,0,1,1,1,0},
{0,1,0,1,0,1,0,0},
{0,0,0,0,0,0,0,0},
{1,0,0,0,0,0,0,1},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};
intfreecount=54;//初始时空闲页块数
typedefstructyebiao//页表结构体
{
intyehao;//页号
intkuaihao;//块号
structyebiao*next;//指向下一个页表项的指针
}YEBIAO;
typedefstructprogress//进程结构体
{
charname[30];//进程名
intsize;//进程所需内存大小
structprogress*next;//指向下一个页表项的指针
structyebiao*yb;//为其分配内存建立的页表首地址
}PROGRESS;
/*分配内存函数,为进程分配所需要的内存并建立页表*/
YEBIAO*allocation(intsize)
{
YEBIAO*head;
YEBIAO*tem;
intn=0;
tem=(YEBIAO*)malloc(sizeof(YEBIAO));
head=tem;
for(inti=0;;i++)//遍历位图找到空闲的页块
{
if(bitmap[i/8][i%8]==1)continue;//如果页会已被占用直接查下一个页块
if(bitmap[i/8][i%8]==0)
{
bitmap[i/8][i%8]=1;//将空闲的位图标识置为一
tem->yehao=n;//建立一个页表项的页号
tem->kuaihao=i;//对应的块号
tem->next=NULL;
n++;
}
if(n==size)break;//如果已经分配了需要的页块直接退出查找
else
{
tem->next=(YEBIAO*)malloc(sizeof(YEBIAO));
tem=tem->next;
}
}
returnhead;
}
/*回收内存*/
voidrecovery(YEBIAO*a)
{
YEBIAO*b;
while(a->next!
=NULL)
{
bitmap[a->kuaihao/8][a->kuaihao%8]=0;//将页块对应的标识位图对应标志置0
b=a->next;//指向下一个页表项
free(a);//释放页表项占用的空间
a=b;
}
bitmap[a->kuaihao/8][a->kuaihao%8]=0;
free(a);
}
voidoutputyebiao(YEBIAO*a)//输出页表的内容
{
cout<<"-------------------------"<do
{
cout<yehao<kuaihao<a=a->next;
}while(a!
=NULL);//遍历页表链表逐行输出页表项
cout<<"-------------------------"<}
voidoutputbit()//输出主存分配位视图
{
cout<<"主存分配位视图如下:
"<cout<<"------------------------------"<for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
cout<}
cout<}
cout<<"------------------------------"<}
PROGRESS*insert(PROGRESS*head,PROGRESS*b)//插入进程,将进程信息插入进程链表中
{
PROGRESS*tem;
if(head==NULL)//如果进程为空直接将要出入的进程指针赋值给头指针
{
head=b;
b->next=NULL;
}
else//定位到链表的队尾将要插入的进程插入到队尾
{
tem=head;
while(tem->next!
=NULL)
{
tem=tem->next;
}
tem->next=b;
}
returnhead;
}
PROGRESS*getprosess(PROGRESS*head)//输入进程为进程分配空间
{
PROGRESS*a;
charna[30];
intsize;
cout<<"请输入进程名:
";
cin>>na;
cout<<"请输入进程所占内存大小:
";
cin>>size;//上面是输入进程的名称和所用内存空间大小
if(size>freecount)//如果进程
{
cout<<"进程所需内存的大小大于空闲的内存,无法添加进程。
"<returnhead;
}
a=(PROGRESS*)malloc(sizeof(PROGRESS));//开辟空间存放进程信息
strcpy(a->name,na);
a->size=size;//初始化进程的基本信息
freecount-=size;//将可用的页块数减去进程要用的页块数
a->yb=allocation(size);//为进程创建页表
cout<<"进程创建成功!
"<a->next=NULL;
returninsert(head,a);//将进程插入进程链表中
}
voidoutputprosess(PROGRESS*head)//输出进程信息
{
if(head==NULL)//判断进程队列是否为空
{
cout<<"当前没有进程!
"<return;
}
do//进程队列不为空,先输出进程的名称和所占内存的大小。
再输出进程的页表队列
{
cout<<"进程名为:
"<name<<"进程所占内存的大小为:
"<size<<"页"<cout<<"进程的页表如下:
"<outputyebiao(head->yb);
head=head->next;
}while(head!
=NULL);
}
PROGRESS*delecteprosess(PROGRESS*head)//删除进程
{
charna[30];
PROGRESS*a,*b;
cout<<"请输入要删除的进程名:
";//使用进程的名字来删除进程
cin>>na;
if(head==NULL)//如果进程为空,退出函数
{
cout<<"进程链表为空,没有进程可删除。
"<returnNULL;
}
if(strcmp(head->name,na)==0)//如果找到要删除的进程
{
recovery(head->yb);//先删除进程的页表并释放所占的页
freecount+=head->size;//将可用的内存数加上进程所占的内孙
a=head->next;
free(head);//释放进程信息所占得内存空间
cout<<"进程"<"<returna;
}
a=head->next;
b=head;
while(a!
=NULL)//遍历链表找到要删除的进程
{
if(strcmp(a->name,na)==0)
{
recovery(a->yb);
freecount+=a->size;
b->next=a->next;
free(a);
cout<<"进程"<"<returnhead;
}
b=a;
a=a->next;
}
cout<<"您输入的进程名不对,删除进程失败。
"<returnhead;
}
voidoutbiaoti()
{
cout<<"\t\t\t主存空间的分配与回收模拟"<cout<<"您可进行如下操作:
1.查看内存分配情况;2.查看进程;3.添加进程4.删除进程"<cout<<"\t\t可用内存为"<}
voidmain()
{
intn;
PROGRESS*head;//进程的头指针
head=NULL;
system("color2f");
outbiaoti();
for(;;)
{
cin>>n;
switch(n)
{
case1:
outputbit();outbiaoti();break;
case2:
system("cls");outputprosess(head);outbiaoti();break;
case3:
system("cls");head=getprosess(head);outbiaoti();break;
case4:
system("cls");head=delecteprosess(head);outbiaoti();break;
default:
break;
}
}
}
六、运行结果:
第一题:
第二题:
七、实验心得:
这次的实验相对来说较难,之前对内存那块知识也不是很清楚,但通过实验,也参考了很多资料解释,但是还是对内存分配与回收有了更深入更清楚的了解,以后的程序编写不论是实验还是项目开发,无论大小,都应该把程序的整体框架构建好,提高重用性,再进行一步步实现。