操作系统内存分配与回收实验报告.docx
《操作系统内存分配与回收实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统内存分配与回收实验报告.docx(33页珍藏版)》请在冰点文库上搜索。
操作系统内存分配与回收实验报告
西安邮电大学
(计算机学院)
课内实验报告
实验名称:
内存分配与回收
专业名称:
计算机科学与技术
班级:
计科1503
*******
学号(8位):
********
*******
实验日期:
2016年5月23日---2016年6月6日
一.实验目的及实验环境
1.实验目的
掌握内存分配FF,BF,WF策略及实现的思路;
掌握内存回收过程及实现思路;
实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。
2.实验环境
(1)硬件
CPU:
I7-6500
内存:
8G
显示器:
笔记本显示器
硬盘空间:
1TB
(2)软件
虚拟机名称及版本:
Vmware
操作系统名称及版本:
UbuntuKylin16.04
编译器:
gcc
二.实验内容
1、实验前准备工作
阅读参考资料,掌握操作系统内存管理的过程,并熟悉FF,BF,WF内存分配策略以及内存回收策略。
2、实验内容
根据下发ppt内容,内存分配与回收程序要求完成如下功能,具体详细设计要求见ppt。
1-Setmemorysize(default=1024)//设置内存大小
2-Selectmemoryallocationalgorithm//选择内存分配算法FF、BF、WF
3-Newprocess//创建新进程,分配内存
4-Terminateaprocess//终止进程,回收内存
5-Displaymemoryusage//显示内存当前使用情况
0–Exit//程序退出
三.方案设计
1.功能模块图及解释
2.核心数据结构及解释
structfree_block_type//空闲块
{
intsize;
intstart_addr;
structfree_block_type*next;
};
structallocated_block//已分配的内存块
{
intpid;
intsize;
intstart_addr;
charprocess_name[PROCESS_NAME_LEN];
structallocated_block*next;
};
1.Setmemorysize(default=1024):
这个模块是用来设置内存大小的,从键盘获取一个数字,并将它赋值给内存大小;若没有设置,则默认内存的大小为1024。
2.Set_algorithm:
这个模块是用来设置分配算法的,共有三种算法:
首次循环适配算法、最好适配算法、最差适配算法。
从键盘输入一种算法前的序号,根据算法点用不同的函数对内存进行分配;
3.New_process:
此模块是用来创建进程的。
从键盘输入进程号,调用fork()创建进程并为其分配一定大小的内存,若分配成功,则将其连接到已分配链表中,否则分配失败;
4.Kill_process:
此模块是用来杀死进程的。
从键盘输入一个进程号,先调用find_process()函数进行查找,若找到,则调用kill()函数将其杀死并释放内存空间。
5.Display_mem_usage:
此模块是用来显示内存的使用情况的。
将每个进程的内存使用情况显示出来,包括起始地址和内存大小;
6.Do_exit:
这个模块是用来结束程序的,直接调用exit()实现。
3.主要算法流程图及解释
算法调用图
四.测试数据及运行结果
1.正常测试数据(3组)及运行结果;
2.非正常测试数据(2组)及运行结果。
五.总结
1.实验过程中遇到的问题及解决办法;
实验过程中不会实现最佳适应算法,然后通过网上查阅别人的算法,自己研究,解决了这个问题。
2.对设计及调试过程的心得体会。
这次实验让我充分了解了内存管理的机制,进一步加深了对计算机的了解,对于以后系统的研究学习计算机起到了至关重要的作用。
六.附录:
源代码(电子版)
#include
#include
#include
/*常量定义*/
#definePROCESS_NAME_LEN32/*进程名长度*/
#defineMIN_SLICE10/*最小碎片的大小*/
#defineDEFAULT_MEM_SIZE1024/*内存大小*/
#defineDEFAULT_MEM_START0/*起始位置*/
/*内存分配算法*/
#defineMA_FF1
#defineMA_BF2
#defineMA_WF3
/*描述每一个空闲块的数据结构*/
structfree_block_type{
intsize;
intstart_addr;
structfree_block_type*next;
};
/*每个进程分配到的内存块的描述*/
structallocated_block{
intpid;
intsize;
intstart_addr;
charprocess_name[PROCESS_NAME_LEN];
structallocated_block*next;
};
/*指向内存中空闲块链表的首指针*/
structfree_block_type*free_block;
/*进程分配内存块链表的首指针*/
structallocated_block*allocated_block_head=NULL;
intmem_size=DEFAULT_MEM_SIZE;/*内存大小*/
intma_algorithm=MA_FF;/*当前分配算法*/
staticintpid=0;/*初始pid*/
intflag=0;/*设置内存大小标志,防止重复设置*/
voiddisplay_menu();
voiddo_exit();
structfree_block_type*init_free_block(intmem_size);
voidset_mem_size();
voidset_algorithm();
voidnew_process();
voidkill_process();
voiddisplay_mem_usage();
voidrearrange(intchoice);
voidabc();
voidrearrage_BF();
voidrearrage_WF();
main(){
charchoice;
pid=0;
free_block=init_free_block(mem_size);//初始化空闲区
display_menu();
while
(1){
printf("Pleasechoice:
");
fflush(stdin);
choice=getchar();//获取用户输入
switch(choice){
case'1':
set_mem_size();//设置内存大小break;
case'2':
set_algorithm();//设置算法flag=1;break;
case'3':
new_process();//创建新进程flag=1;break;
case'4':
kill_process();//删除进程flag=1;break;
case'5':
display_mem_usage();//显示内存使用flag=1;break;
case'0':
do_exit();//释放链表并退出exit(0);
default:
break;
}
choice=getchar();
}
}
//紧缩处理
voidfree_memory_rearrage(intmemory_reduce_size,intallocated_size)
{
structfree_block_type*p1,*p2;
structallocated_block*a1,*a2;
if(memory_reduce_size!
=0)//分配完还有小块空间
{
p1=free_block;
p2=p1->next;
p1->start_addr=0;
p1->size=memory_reduce_size;
p1->next=NULL;
mem_size=memory_reduce_size;//
}
else
{
p2=free_block;
free_block=NULL;
mem_size=0;
}
while(p2!
=NULL)//释放节点
{
p1=p2;
p2=p2->next;
free(p1);
}
//allocated_block重新修改链接
a1=(structallocated_block*)malloc(sizeof(structallocated_block));
a1->pid=pid;
a1->size=allocated_size;
a1->start_addr=memory_reduce_size;//已申请的开始地址,从memory_reduce_size开始
sprintf(a1->process_name,"PROCESS-%02d",pid);
a1->next=allocated_block_head;
a2=allocated_block_head;
allocated_block_head=a1;
while(a2!
=NULL)
{
a2->start_addr=a1->start_addr+a1->size;
a1=a2;
a2=a2->next;
}
}
intallocate_mem(structallocated_block*ab)
{
structfree_block_type*fbt,*pre;
intrequest_size=ab->size;
//intmemory_count;//计算剩余分区总内存大小
fbt=pre=free_block;
while((pre!
=NULL)&&(request_size>pre->size))//遍历查找匹配空白区
{
//memory_count+=pre->size;
fbt=pre;
pre=pre->next;
}
if(!
pre)//pre=pre->next结尾
{
if(mem_size>=request_size)/*memory_count*/
{
if(mem_size>=request_size+MIN_SLICE)
free_memory_rearrage(mem_size-request_size,request_size);//采用紧缩技术
else
free_memory_rearrage(0,mem_size);//采用紧缩技术,空间全部分配
return0;//全部重定位,不返回上级
}
else
return-1;//分配失败!
}
else//内存能满足request_size<=pre->size
{
if((pre->size-request_size)>MIN_SLICE)//找到可满足空闲分区且分配后剩余空间足够大,则分割
{
pre->size=pre->size-request_size;
ab->start_addr=pre->start_addr+pre->size;
}
else//找到可满足空闲分区且但分配后剩余空间比较小,则一起分配,删除该节点
{
if(pre==fbt)
{
fbt=pre->next;
free_block=fbt;
}
else
fbt->next=pre->next;
ab->start_addr=pre->start_addr;
ab->size=pre->size;
free(pre);//释放节点
}
}
mem_size-=ab->size;//...
rearrange(ma_algorithm);//分配成功,按照相应算法排序
return1;
}
voidnew_process()
{
structallocated_block*ab;
intsize;
intret;/*ret==1表示从空闲分区分配空间成功*/
if(mem_size==0)
{
printf("内存全部分配!
无法创建新进程,请先释放其他进程!
\n");
return;
}
ab=(structallocated_block*)malloc(sizeof(structallocated_block));
if(ab==NULL)
{
printf("NoMem!
\n");
exit
(1);
}
ab->next=NULL;
pid++;
sprintf(ab->process_name,"PROCESS-%02d",pid);//字符串格式化
ab->pid=pid;
while
(1)
{
printf("Pleaseinputthememoryfor%s(0-%d):
",ab->process_name,mem_size);
scanf("%d",&size);
if(size<=mem_size&&size>0)
{
ab->size=size;
break;
}
printf("Pleaseinputagain!
\n");
}
ret=allocate_mem(ab);//从空闲内存分配空间
/*如果此时allocated_block_head尚未赋值,则赋值*/
if((ret==1)&&(allocated_block_head==NULL))
allocated_block_head=ab;
elseif(ret==1)/*分配成功,将该已分配块的描述插入已分配链表(头插<无头节点>)*/
{
ab->next=allocated_block_head;
allocated_block_head=ab;
}
elseif(ret==-1)/*分配不成功*/
{
printf("Allocationfail\n");
free(ab);
return;
}
printf("AllocationSuccess!
\n");
}
structallocated_block*find_process(intpid)
{
structallocated_block*p;
p=allocated_block_head;
while(p)
{
if(p->pid==pid)
returnp;
p=p->next;
}
returnp;
}
/*释放ab所表示的分配区*/
intfree_mem(structallocated_block*ab)
{
intalgorithm=ma_algorithm;
structfree_block_type*fbt,*pre,*work;
mem_size+=ab->size;
fbt=(structfree_block_type*)malloc(sizeof(structfree_block_type));
if(!
fbt)
return-1;
fbt->size=ab->size;
fbt->start_addr=ab->start_addr;
fbt->next=NULL;
rearrange(MA_FF);
pre=NULL;
work=free_block;
//查找插入位置
while((work!
=NULL)&&(fbt->start_addr>work->start_addr))
{
pre=work;
work=work->next;
}
if(!
pre)//插入开始位置
{
if(!
work)
{
free_block=fbt;//
}else
{
fbt->next=work;
free_block=fbt;
if(fbt->start_addr+fbt->size==work->start_addr)//2)
{
fbt->next=work->next;
fbt->size=fbt->size+work->size;
free(work);
}
}
}
else
{
if(!
work)
{
pre->next=fbt;
if(fbt->start_addr==pre->start_addr+pre->size)//1)
{
pre->next=work;
pre->size=fbt->size+pre->size;
free(fbt);
}
}
else
{
fbt->next=work;
pre->next=fbt;
//检查并合并相邻的空闲分区
if((fbt->start_addr==pre->start_addr+pre->size)&&(fbt->start_addr+fbt->size==work->start_addr))//3)
{
pre->next=work->next;
pre->size=pre->size+fbt->size+work->size;
free(fbt);
free(work);
}
elseif(fbt->start_addr==pre->start_addr+pre->size)//1)
{
pre->next=work;
pre->size=pre->size+fbt->size;
free(fbt);
}
elseif(work->start_addr==fbt->start_addr+fbt->size)//2
{
fbt->next=work->next;
fbt->size=work->size+fbt->size;
free(work);
}
}
}
//将空闲链表重新按照当前算法排序
rearrange(ma_algorithm);
return1;
}
/*释放ab数据结构节点*/
voiddispose(structallocated_block*free_ab)
{
structallocated_block*pre,*ab;
if(free_ab==allocated_block_head)/*如果要释放第一个节点*/
{
allocated_block_head=free_ab->next;
free(free_ab);
return;
}
pre=allocated_block_head;
ab=allocated_block_head->next;
while(ab!
=free_ab)
{
pre=ab;
ab=ab->next;
}
pre->next=ab->next;
free(ab);
}
voidkill_process()
{
structallocated_block*ab;
intpid;
printf("Killprocess,inputpid=");
scanf("%d",&pid);
ab=find_process(pid);
if(ab!
=NULL)
{
free_mem(ab);/*释放ab所表示的分配区*/
dispose(ab);/*释放ab数据结构节点*/
printf("KillProcessSuccess!
\n");
return;
}
printf("KillProcessFailure!
\n");
}
/*显示当前内存的使用情况,包括空闲区的情况和已经分配的情况*/
voiddisplay_mem_usage()
{
structfree_block_type*fbt=free_block;
structallocated_block*ab=allocated_block_head;
/*显示空闲区*/
printf("----------------------------------------------------------\n");
if(fbt==NULL)
printf("内存全部分配!
\n");
else
{
printf("FreeMemory:
\n");
printf("%20s%20s\n","\tstart_addr","size");
while(fbt!
=NULL)
{
printf("%20d%20d\n",fbt->start_addr,fbt->size);
fbt=fbt->next;
}
}
printf("----------------------------------------------------------\n");
/*显示已分配区*/
if(ab==NULL)
printf("尚未开始分配!
\n");
else
{
printf("\nUsedMemory:
\n");
printf("%10s%20s%10s%10s\n","\tPID","ProcessName","start_addr","size");
while(ab!
=NULL)
{
printf("%10d%20s%10d%10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size);
ab=ab->next;
}
}
pr