操作系统内存buddy算法和页置换算法实验报告.doc
《操作系统内存buddy算法和页置换算法实验报告.doc》由会员分享,可在线阅读,更多相关《操作系统内存buddy算法和页置换算法实验报告.doc(14页珍藏版)》请在冰豆网上搜索。
操作系统内存buddy算法和页置换算法实验报告
一、实验目的
通过模拟实现内存分配的伙伴算法和请求页式存储管理的几种基本页面置换算法,了解存储技术的特点。
掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容
1.实现一个内存管理的伙伴算法,实现内存块申请时的分配和释放后的回收。
2.设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。
1)最佳置换算法(Optimal)
2)先进先出法(FisrtInFirstOut)
3)最近最久未使用(LeastRecentlyUsed)
4)最不经常使用法(LeastFrequentlyUsed)
其中,命中率=1-页面失效次数/页地址流长度
试对上述算法的性能加以较各:
页面个数和命中率间的关系;同样情况下的命中率比较。
三、项目要求及分析
1、要求:
用随机函数仿真程序进行内存申请,并且以较为随机的次序进行释放。
对其碎片进行统计,当申请分配内存失败时区分实际空间不足和由于碎片而不能满足。
分析:
总的内存大小固定(默认为2048),申请内存的时候用到随机函数,为了使分配效果更加突出,每次申请内存大小为1——600。
每次申请完并成功分配后,得到剩余内存大小availMemory和碎片大小fragment[],来得到分配失败的原因。
分配成功的内存集记录为haveAllo[],在haveAllo[]中随机抽取内存进行释放。
2、要求:
首先用srand()和rand()函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
分析:
可以直接忽略指令的内容,按照地址来进行分析,这样是执行更加方便。
各个算法总体相同,主要区别就是置换的条件不同,掌握好条件是本实验的关键。
四、具体实现
4.1流程图:
1、分配内存:
释放内存:
2、
(1)最佳置换算法(Optimal)
(2)先进先出法(FisrtInFirstOut)
(3)最近最久未使用(LeastRecentlyUsed)4)最不经常使用法(LeastFrequentlyUsed)
4.2数据结构定义:
1、
typedefstructMemoryTree{
structMemoryTree*left;
structMemoryTree*right;
structMemoryTree*father;
inttab;
intthisMemory;
intused;
}TreeNode,*Mtree;
内存节点定义:
tab为可用标记,1为可用,0为已用
thisMemory表示此节点共有内存量
used表示已用内存量
intAlloMemory(inttoBeAllo,Mtreeroot)
分配内存
voidReleaseMemory(inttoBeRele,Mtreeroot)
释放内存
voidDelete(inta[],intnum)
从数组a中删除元素num,该函数用于内存释放。
voidScanMemory(Mtreeroot)
浏览分配树,以得到可用内存和碎片
2、
voidinit_addr(void)
初始化指令序列,并按照一定规则执行
voidinit_page(void)
初始化页表
intisIn(inta)
判断地址为a的指令是否在页中
intfind_max(intnum,intdata[])
找出data序列中第一个最大值的序号
intfind_min(intnum,intdata[])
找出data序列中第一个最小值的序号
floatoptimal(void)
optimal算法,返回命中率
floatFIFO(void)
FIFO算法,返回命中率
floatLRU(void)
LRU算法,返回命中率
floatLFU(void)
LFU算法,返回命中率
五、调试运行结果
1、假设有3次分配,然后释放。
结果如下:
若分配次数增加,假设变为7次,结果如下:
我们发现,出现两次碎片过多引起的分配失败。
释放过程只释放5次就结束了,不会释放非配失败的内存:
2、我们进行对页表大小为1、5、10、15、20、25、32来进行模拟,结果如下:
(1)页表大小为1
(2)页表大小为5
(3)页表大小为10(4)页表大小为15
(5)页表大小为20(6)页表大小为25
(7)页表大小为32
六、所遇问题及解决办法
1、P:
在数组传递参数时出错
A:
发现很多需要传递的数组时贯穿全局的,所以设置为全局变量,不再进行参数的传递
2、P:
在合并可用伙伴内存的时候不知道如何去进行未知次数的合并
A:
调用递归,进行树的后续遍历,先合并再判断,使问题迎刃而解。
3、P:
在分配指令序列的时候,没有考虑到极端情况:
如有320条指令,第一次随机的m为320,第m+1条指令不存在。
A:
把此时的第m条指令作为地址流中的一个,此处理不影响全局的概率。
附:
程序代码:
1、内存分配与释放:
#include
#include
#include
#defineMEMORY2048
intavailable[100],avaiNum=0,avaiMemory=MEMORY;
intfragment[100],fragNum=0;
typedefstructMemoryTree{
structMemoryTree*left;
structMemoryTree*right;
structMemoryTree*father;
inttab;
intthisMemory;
intused;
}TreeNode,*Mtree;
intAlloMemory(inttoBeAllo,Mtreeroot)
{
if(toBeAllo>avaiMemory){
return0;
}elseif(toBeAllo>root->thisMemory){
return-1;
}elseif(toBeAllo>root->thisMemory/2){
if((root->left==NULL)&&(root->tab==0)){
root->tab=1;
root->used=toBeAllo;
return1;
}else
return-1;
}elseif(root->tab==1){
return-1;
}else{
if(root->left==NULL){
root->left=(Mtree)malloc(sizeof(TreeNode));
root->left->tab=0;
root->left->thisMemory=root->thisMemory/2;
root->left->used=0;
root->left->left=NULL;
root->left->right=NULL;
root->left->father=root;
root->right=(Mtree)malloc(sizeof(TreeNode));
root->right->tab=0;
root->right->thisMemory=root->thisMemory/2;
root->right->used=0;
root->right->left=NULL;
root->right->right=NULL;
root->right->father=root;
}
if(AlloMemory(toBeAllo,root->left)!
=1)
returnAlloMemory(toBeAllo,root->right);
else
return1;
}
}
voidReleaseMemory(inttoBeRele,Mtreeroot)
{
Mtreetemp;
if(root!
=NULL){
ReleaseMemory(toBeRele,root->left);
ReleaseMemory(toBeRele,root->right);
if(root->left==NULL){
if((root->tab==0)&&(root->father!
=NULL)){
if((root->father->left->tab==0)&&(root->father->right->tab==0)&&(root->father->left->left==NULL)&&(root->father->right->left==NULL)){
temp=root->father;
temp->left=NULL;
temp->right=NULL;
}
}elseif((root->tab==1)&&(root->used==toBeRele)){
root->used=0;
root->tab=0;
if((root->father->left->tab==0)&&(root->father->right->tab==0)&&(root->father->left->left==NULL)&&(root->father->right->left==NULL)){
temp=root->father;
temp->left=NULL;
temp->right=NULL;
}
}
}
}
}
voidDelete(inta[],intnum)
{
inti=num;
while(a[i]!
='\0'){
a[i]=a[i+1];
i++;
}
}
voidScanMemory(Mtreeroot)
{
if(root->left==NULL){
if(root->tab==0)
available[avaiNum++]=root->thisMemory;
else
fragment[fragNum++]=root->thisMemory-root->used;
}else{
ScanMemory(root->left);
S