1、动态分区存储管理方式的主存分配回收2011-2012-1操作系统课程实验报告实验名称 动态分区存储管理方式的主存分配回收班 级 学 号 姓 名 成 绩 一、实验目的深入了解动态分区存储管理方式主存分配回收的实现。二、实验要求编写程序完成动态分区存储管理方式的主存分配回收的实现。实验具体包括:首先确定主存空间分配表;然后采用最优适应算法完成主存空间的分配和回收;最后编写主函数对所做工作进行测试。三、实验步骤实现动态分区的分配和回收,主要考虑的问题有三个:第一,设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计主存分配算法:第三,在设计的数据表格基础上
2、设计主存回收算法。首先,考虑第个问题:设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域。 由于动态分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。主存分配时查找空闲区进行分配,然后填写已分配区表,主要操作在空闲区;某个作业执行完后,将该
3、分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。由此可见,主存的分配和回收主要是对空闲区的操作。这样为了便于对主存空间的分配和回收,就建立两张分区表记录主存使用情况一张表格记录作业占用分区的“已分配区表”一张是记录空闲区的“空闲区表”。这两张表的实现方法一般有两种,一种是链表形式,一种是顺序表形式。在试验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须是提前固定,所以无论是“已分配区表”还是“空闲区表”都必须事先确定长度。他们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因而在多数情况下,无论是“已分配区表”还是“空闲区表”都有空闲栏目。已分配区表中除了分区起始地
4、址、长度外,也至少还有一项“标志”,如果是空闲栏目,内容为“空”,如果为某个作业占用分区的登记项,内容为该作业的作业名;空闲区表中除了分区起始地址、长度外,也要有一项“标志”,如果是空闲栏目,内容为“空”,如果为某个空闲区的登记项,内容为“未分配”。在实际系统中,这两表格的内容可能还要多,实验中仅仅使用上述必须的数据。为此,“已分配区表”和“空闲区表”可变分区管理方式将内存除操作系统占用区域外的空间看做一个大的空闲区。当作业要求装入内存时,根据作业需要内存空间的大小 查询内存中的各个空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装
5、人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。四、实验结果程序代码:#include #include float minsize=5;int count1=0;int count2=0;#define m 10 #define n 10 structfloat address; float length; int flag; used_tablen; structfloat address; float length; int flag; free_tablem; void initialize(void
6、);int distribute(int, float);int recycle(int);void show();void initialize(void) int a; for(a=0; a=n-1; a+) used_tablea.flag=0; free_table0.address=1000; free_table0.length=1024; free_table0.flag=1;int distribute(int process_name, float need_length) int i, k=-1; float ads, len; int count=0; i=0; whil
7、e(i=m-1) if(free_tablei.flag=1 & need_length =free_tablei.length) count+; if(count=1|free_tablei.length free_tablek.length) k=i; i=i+1; if(k!=-1) if(free_tablek.length-need_length)=minsize) free_tablek.flag=0; ads=free_tablek.address; len=free_tablek.length; else ads=free_tablek.address; len=need_le
8、ngth; free_tablek.address+=need_length; free_tablek.length-=need_length; i=0; while(used_tablei.flag!=0) i=i+1; if(i=n-1) used_tablei.address=ads; used_tablei.length=len; used_tablei.flag=process_name; count1+; else if(free_tablek.flag = 0) free_tablek.flag=1; free_tablek.address=ads; free_tablek.le
9、ngth=len; else free_tablek.address=ads; free_tablek.length+=len; cout内存分配区已满,分配失败!n; return 0; else cout 无法为该作业找到合适分区!n; return 0; return process_name;int recycle(int process_name) int y=0; float recycle_address, recycle_length; int i, j, k; int x; while(y=n-1&used_tabley.flag!=process_name) y=y+1;
10、if(y=n-1) recycle_address=used_tabley.address; recycle_length=used_tabley.length; used_tabley.flag=0; count2+; else cout=m|(k!=-1&j!=-1) if(free_tablei.flag=1) if(free_tablei.address+free_tablei.length)=recycle_address) k=i; if(recycle_address+recycle_length)=free_tablei.address) j=i; i=i+1; if(k!=-
11、1) if(j!=-1) free_tablek.length+=free_tablej.length+recycle_length; free_tablej.flag=0; else free_tablek.length+=recycle_length; else if(j!=-1) free_tablej.length+=recycle_length; free_tablej.address=recycle_address; else x=0; while(free_tablex.flag!=0) x=x+1; if(x=m-1) free_tablex.length=recycle_le
12、ngth; free_tablex.flag=1; else used_tabley.flag=process_name; cout空闲区已满,回收失败!n; return 0; return process_name;void show() cout 空 闲 区n; for(int i=0;i=count2;i+) cout地址:free_tablei.address 作业长度:free_tablei.length 状 态:free_tablei.flagendl; cout已 分 配 区n; for(int j=0;jcount1;j+) cout地址:used_tablej.addres
13、s 作业长度:used_tablej.length 作业名:used_tablej.flagendl;void main() int choice; int job_name; float need_memory; bool exitFlag=false; cout 动态分区分配方式的模拟 n; initialize(); while(!exitFlag) cout1: 分配内存 2: 回收内存n; coutchoice; switch(choice) case 0: exitFlag=true; break; case 1: coutjob_nameneed_memory; distribu
14、te(job_name, need_memory); break; case 2: int ID; coutID; recycle(ID); break; case 3: show(); break; 内存分配回收实现截图(1)、假定系统内存分配表允许的最大作业项为10,当分配超过10时,提示“内存分配区已满,分配失败”。(2)、回收作业所占内存时,当输入的作业名不存在,回收失败,提示“该作业不存在”。(3)、当要释放某个作业时,将已分配表中此作业的标志置为0,并在空闲区做相应登记。五、总结核心算法:/最优分配算法实现的动态分区int distribute(int process_name,
15、float need_length) int i, k=-1; /k用于定位在空闲表中选择的未分配栏 float ads, len; int count=0; i=0; /核心的查找条件,找到最优空闲区 while(i=m-1) /循环找到最佳的空闲分区 if(free_tablei.flag=1 & need_length =free_tablei.length) count+; if(count=1|free_tablei.length free_tablek.length) k=i; i=i+1; if(k!=-1) if(free_tablek.length-need_length)=
16、minsize) /整个分配 free_tablek.flag=0; ads=free_tablek.address; len=free_tablek.length; else /切割空闲区 ads=free_tablek.address; len=need_length; free_tablek.address+=need_length; free_tablek.length-=need_length; i=0; /循环寻找内存分配表中标志为空栏目的项while(used_tablei.flag!=0) i=i+1; if(i=n-1) /找到,在已分配区表中登记一个表项 used_tabl
17、ei.address=ads; used_tablei.length=len; used_tablei.flag=process_name; count1+; else /已分配区表长度不足 if(free_tablek.flag = 0) /将已做的整个分配撤销 free_tablek.flag=1; free_tablek.address=ads; free_tablek.length=len; else /将已做的切割分配撤销 free_tablek.address=ads; free_tablek.length+=len; cout内存分配区已满,分配失败!n; return 0; e
18、lse cout 无法为该作业找到合适分区!n; return 0; return process_name;每一次的实践,都会有很大的收获。决定做这个题目的时候,就针对此题要解决的几个问题反复思考,重新翻开教科书把相关内容特别是算法原理认真细致的看了一遍,设想会遇到的问题。在内存动态分配程序设计中,最优适应算法比首次要难一些,要加上对分配后该分区是否能最好地利用的判断。再一个问题是回收时候的合并,对地址的修改不是很有把握。着手写程序后,半天才理清回收的内存和上下邻合并的条件与关系,写此处的代码时,逻辑上比较混乱,反复错误反复修改了很多次才调试正确,这也是花了最多时间才得以正确实现的部分。六、参考文献XX文库
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1