可变分区存储管理方案中的内存分配

合集下载

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

课程设计2可变分区存储管理方式的内存分配回收一、课程设计目的深入了解采用可变分区存储管理方式的内存分配回收的实现;二、预备知识存储管理中可变分区的管理方式;三、小组成员四、课程设计内容编写程序完成可变分区存储管理方式的内存分配回收;具体包括:确定内存空间分配表;采用最优适应算法完成内存空间的分配和回收;编写主函数对所做工作进行测试;五、设计思路:整体思路:可变分区管理方式将内存除操作系统占用区域外的空间看做一个大的空闲区;当作业要求装入内存时,根据作业需要内存空间的大小查询内存中的各个空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区;如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区;设计所才用的算法:采用最优适应算法,每次为作业分配内存时,总是把既能满足要求、又是最小的空闲分区分配给作业;但最优适应算法容易出现找到的一个分区可能只比作业所需求的长度略大一点的情行,这时,空闲区分割后剩下的空闲区就很小以致很难再使用,降低了内存的使用率;为解决此问题,设定一个限值minsize,如果空闲区的大小减去作业需求长度得到的值小于等于minsize,不再将空闲区分成己分分区和空闲区两部分,而是将整个空闲区都分配给作业;内存分配与回收所使用的结构体:为便于对内存的分配和回收,建立两张表记录内存的使用情况;一张为记录作业占用分区的“内存分配表”,内容包括分区起始地址、长度、作业名/标志为0时作为标志位表示空栏目;一张为记录空闲区的“空闲分区表”,内容包括分区起始地址、长度、标志0表空栏目,1表未分配;两张表都采用顺序表形式;关于分配留下的内存小碎片问题:当要装入一个作业时,从“空闲分区表”中查找标志为“1”未分配且满足作业所需内存大小的最小空闲区,若空闲区的大小与作业所需大小的差值小于或等于minsize,把该分区全部分配给作业,并把该空闲区的标志改为“0”空栏目;同时,在已分配区表中找到一个标志为“0”的栏目登记新装人作业所占用分区的起始地址,长度和作业名;若空闲区的大小与作业所需大小的差值大于minsize;则把空闲区分成两部分,一部分用来装入作业,另外一部分仍为空闲区;这时只要修改原空闲区的长度,且把新装人的作业登记到已分配区表中;内存的回收:在可变分区方式下回收内存空间时,先检查是否有与归还区相邻的空闲区上邻空闲区,下邻空闲区;若有,则将它们合件成一个空闲区;程序实现时,首先将要释放的作业在“内存分配表”中的记录项的标志改为“0”空栏目,然后检查“空闲区表”中标志为‘1’未分配的栏目,查找是否有相邻的空闲区,若有,将之合并,并修改空闲区的起始地址和长度;六:数据结构1已分配表的定义:struct{floataddress;//已分分区起始地址floatlength; //已分分区长度,单位为字节intflag; //已分配区表登记栏标志,"0"表示空栏目,实验中只支持一个字符的作业名}used_tablen; //已分配区表2空闲分区表的定义:struct{floataddress; //空闲区起始地址floatlength; //空闲区长度,单位为字节intflag; //空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配}free_tablem; //空闲区表3全局变量floatminsize=5;definen10 //假定系统允许的最大作业数量为ndefinem10 //假定系统允许的空闲区表最大为m七、核心算法://最优分配算法实现的动态分区intdistributeintprocess_name,floatneed_length{inti,k=-1; //k用于定位在空闲表中选择的未分配栏floatads,len;intcount=0;i=0;//核心的查找条件,找到最优空闲区whilei<=m-1//循环找到最佳的空闲分区{iffree_tablei.flag==1&&need_length<=free_tablei.length{count++;ifcount==1||free_tablei.length<free_tablek.lengthk=i;}i=i+1;}ifk=-1{iffree_tablek.length-need_length<=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;//循环寻找内存分配表中标志为空栏目的项whileused_tablei.flag=0{i=i+1;}ifi<=n-1//找到,在已分配区表中登记一个表项{used_tablei.address=ads;used_tablei.length=len;used_tablei.flag=process_name;count1++;}else//已分配区表长度不足{iffree_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";return0;}}else{cout<<"无法为该作业找到合适分区\n";return0;}returnprocess_name;}八、程序流程图:作业分配流程图:内存回收流程图:九、程序说明:本程序采用VisualC++编写,模拟可变分区存储管理方式的内存分配与回收;假定系统允许的最大作业数量为n=10,允许的空闲区表最大项数为m=10,判断是否划分空闲区的最小限值为minsize=5;初始化用户可占用内存区的首地址为1000,大小为1024B;定义两个结构体及其对象free_tablem和used_tablen实现内存的分配回收及分配表和空闲表的登记;用最优分配算法实现动态分配时,调用intdistributeintprocess_name,floatneed_length内存分配函数,设定循环条件查找最佳空闲分区,定义intk以记录最佳空闲区的首地址,根据找到的空闲区大小和作业大小判断是整个分配给作业还是切割空闲区后再分配给作业,并在“内存分配表”和“空闲分区表”中作登记;调用intrecycleintprocess_name函数实现内存的回收;顺序循环“内存分配表”找到要回收的作业,将标志位设为“0”,定义floatrecycle_address,recycle_length;用recycle_address 记下回收作业的首地址,recycle_length记下回收作业长度;查找空闲表,如果free_tablei.address+free_tablei.length==recycle_address,说明有上邻接空闲区,这时上邻接区的起始地址不变,长度+recycle_address;如果recycle_address+recycle_length==free_tablei.address,说明有下邻接,这时下邻接空闲区的起始地址改为回收作业的起始地址recycle_address,长度+recycle_length;如果同时有上下邻接空闲区,则上邻接的起始地址不变,长度+recycle_address+下邻接的长度,下邻接标志设为“0”否则,要回收的内存没有邻接空闲区,在空闲区中找到一个标志为“0”的空栏目登记回收的内存;十、内存分配回收实现截图:1、后台代码的截图:1、假定系统内存分配表允许的最大作业项为10,当分配超过10时,提示“内存分配区已满,分配失败”;2、回收作业所占内存时,当输入的作业名不存在,回收失败,提示“该作业不存在”;3、当要释放某个作业时,将已分配表中此作业的标志置为‘0’,并在空闲区做相应登记;4、分配的作业大小21B与找到的最优空闲区大小25B差值小于5B,所以将整块空闲区直接分配给作业;5、分配的作业大小14B与找到的最优空闲区大小20B差值大于5B,所以将整块空闲区分割成两部分,然后修改空闲表;6、要回收的内存在空闲表中有上邻,将其合并7、空闲区有两个长度分别为20B和18B的未分配烂,现为作业6分配14B的内存,用最佳分配算法找到空闲区;2、制作界面的实现截图十、源程序:include<iostream.h>include<iomanip.h>//全局变量floatminsize=5;intcount1=0;intcount2=0;definem10 //假定系统允许的空闲区表最大为mdefinen10 //假定系统允许的最大作业数量为n//已分配表的定义struct{floataddress;//已分分区起始地址floatlength; //已分分区长度,单位为字节intflag; //已分配区表登记栏标志,"0"表示空栏目}used_tablen; //已分配区表对象名//空闲区表的定义:struct{floataddress; //空闲区起始地址floatlength; //空闲区长度,单位为字节intflag; //空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配}free_tablem; //空闲区表对象名//函数声明voidinitializevoid;intdistributeint,float;intrecycleint;voidshow;//初始化两个表voidinitializevoid{inta;fora=0;a<=n-1;a++used_tablea.flag=0; //已分配表的表项全部置为空表项free_table0.address=1000;free_table0.length=1024;free_table0.flag=1; //空闲区表的表项全部为未分配}//最优分配算法实现的动态分区intdistributeintprocess_name,floatneed_length{inti,k=-1; //k用于定位在空闲表中选择的未分配栏floatads,len;intcount=0;i=0;whilei<=m-1//循环找到最佳的空闲分区{iffree_tablei.flag==1&&need_length<=free_tablei.length{count++;ifcount==1||free_tablei.length<free_tablek.lengthk=i;}i=i+1;}ifk=-1{iffree_tablek.length-need_length<=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;//循环寻找内存分配表中标志为空栏目的项whileused_tablei.flag=0{i=i+1;}ifi<=n-1//找到,在已分配区表中登记一个表项{used_tablei.address=ads;used_tablei.length=len;used_tablei.flag=process_name;count1++;}else//已分配区表长度不足{iffree_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";return0;}}else{cout<<"无法为该作业找到合适分区\n";return0;}returnprocess_name;}intrecycleintprocess_name{inty=0;floatrecycle_address,recycle_length;inti,j,k; //j栏是下邻空闲区,k栏是上栏空闲区intx;//在内存分配表中找到要回收的作业whiley<=n-1&&used_tabley.flag=process_name{ y=y+1;}ify<=n-1//找到作业后,将该栏的标志置为‘0’{recycle_address=used_tabley.address;recycle_length=used_tabley.length;used_tabley.flag=0;count2++;}else//未能找到作业,回收失败{cout<<"该作业不存在\n";return0;}j=k=-1;i=0;whilei>=m||k=-1&&j=-1//修改空闲分区表{iffree_tablei.flag==1{ iffree_tablei.address+free_tablei.length==recycle_address k=i; //判断是否有上邻接ifrecycle_address+recycle_length==free_tablei.addressj=i; //判断是否有下邻接}i=i+1;}//合并空闲区ifk=-1//回收区有上邻接{ifj=-1{ //回收区也有下邻接,和上下领接合并free_tablek.length+=free_tablej.length+recycle_length;free_tablej.flag=0; //将第j栏的标记置为‘0’}else //不存在下邻接,和上邻接合并free_tablek.length+=recycle_length;}elseifj=-1{ //只有下邻接,和下邻接合并free_tablej.length+=recycle_length;free_tablej.address=recycle_address;}else{ //上下邻接都没有x=0;whilefree_tablex.flag=0x=x+1; //在空闲区表中查找一个状态为‘0’的栏目ifx<=m-1{ //找到后,在空闲分区中登记回收的内存free_tablex.address=recycle_address;free_tablex.length=recycle_length;free_tablex.flag=1;}else{ //空闲表已满,执行回收失败used_tabley.flag=process_name;cout<<"空闲区已满,回收失败\n";return0;}}returnprocess_name;}voidshow//程序执行时输出模拟的内存分配回收表{cout<<"+++++++++++++++++++++++++++++++++++++++\n";cout<<"+++++++空闲区+++++++\n";cout<<"+++++++++++++++++++++++++++++++++++++++\n";forinti=0;i<=count2;i++cout<<"地址:"<<free_tablei.address<<""<<"作业长度:"<<free_tablei.length<<""<<"状态:"<<free_tablei.flag<<endl;cout<<"+++++++++++++++++++++++++++++++++++++++\n";cout<<"+++++++已分配区++++++\n";cout<<"+++++++++++++++++++++++++++++++++++++++\n";forintj=0;j<count1;j++cout<<"地址:"<<used_tablej.address<<""<<"作业长度:"<<used_tablej.length<<""<<"作业名:"<<used_tablej.flag<<endl;}voidmain//主函数调用各功能函数对所有工作进行测试{intchoice;//用来选择将要进行的操作intjob_name;floatneed_memory;boolexitFlag=false;cout<<"动态分区分配方式的模拟\n";cout<<"\n";cout<<"请选择操作类型:\n";initialize;//开创空闲区和已分配区两个表whileexitFlag{cout<<"\n";cout<<"1:分配内存2:回收内存\n";cout<<"3:查看分配0:退出\n";cout<<"\n";cout<<"请输入您的操作:";cin>>choice;switchchoice{case0:exitFlag=true;//退出操作break;case1:cout<<"请输入作业名和所需内存:";cin>>job_name>>need_memory;distributejob_name,need_memory;//分配内存break;case2:intID;cout<<"请输入您要释放的分区号:";cin>>ID;recycleID;//回收内存break;case3:show;break;}}}十一、心得体会:每一次的实践,都会有很大的收获;决定做这个题目的时候,就针对此题要解决的几个问题反复思考,重新翻开教科书把相关内容特别是算法原理认真细致的看了一遍,设想会遇到的问题;在内存动态分配程序设计中,最优适应算法比首次要难一些,要加上对分配后该分区是否能最好地利用的判断;再一个问题是回收时候的合并,对地址的修改不是很有把握;着手写程序后,半天才理清回收的内存和上下邻合并的条件与关系,写此处的代码时,逻辑上比较混乱,反复错误反复修改了很多次才调试正确,这也是花了最多时间才得以正确实现的部分;之前大多用的c语言,对结构体,对象等知识淡忘了很多,这一次的实践让我找回了很多学过的知识点,也弥补了很多的不足之处;逻辑思维也得到了锻炼,写代码也不再像初学的时候那么繁琐,自己都能感觉到那一点点的进步,顿时也觉得充实起来;还有一个难点就是为作业找到最佳空闲区,此处是参照了一些资料后,理清了条件,然后用一个while两个if语句循环嵌套就实现了此功能;实践中也发现自身很多的不足,比如上理论课时认为已经理解了的算法原理在用代码实践时,发现还是有模糊和思考不周的地方;实践中最困难的是以前没有做过界面,所以虽然程序在大家的努力下还算顺利地完成了,功能测试也通过了,可是界面的制作却成了比较大的难题;好在之前在面向对象课程实验和程序设计课程设计中都用到过MFC,于是确定了用C++来制作界面;但是因为以前界面程序编写较少,所以界面的编写遇到了许多困难,特别是实现内存分配表和空闲分区表的输出遇到了很大的挫折,最后在查阅资料、认真思考的基础上实现内存分配表和空闲分区表的输出,并最终作出了内存管理子系统;在添加控件和消息映射的时候,问题不是很大,但是在对相应控件添加代码和给类添加成员函数的时候,要将源代码对应的部分添加进去,且要注意修包含的头文件;这些地方一直频繁出错,或在功能得不到实现,大家一起边找资料边学习新的知识,通过很多次的尝试,终于做出了界面,虽然不太好看,而且功能也很简单,但这也是也经过大家很大努力才完成的;学习着,收获着,并快乐着,这真是小组成员们共同的感触;对于自身不足的地方,大家也有了比较清晰的认识,对未来的发展,也有了个参照,将遇到的困难一个个跨过,并最终完成此次课程设计,真的感觉很有收获很有成就感;同时也培养了团队合作精神,几次的讨论,大大提升了我们合作的默契度,体会到合作的重要性;动手能力也得到了提高,当然,我们的设计还有很多的不足之处,有些问题没能很好解决,但通过不断学习和实践,我们一定会做的更好;。

可变分区存储管理的内存分配算法模拟实现----最佳适应算法

可变分区存储管理的内存分配算法模拟实现----最佳适应算法

可变分区存储管理的内存分配算法模拟实现----最佳适应算法可变分区存储管理是一种内存管理技术,其通过将内存分割成不同大小的区域来存储进程。

每个进程被分配到与其大小最匹配的区域中。

内存分配算法的选择影响了系统的性能和资源利用率。

本文将介绍最佳适应算法,并模拟实现该算法。

一、什么是最佳适应算法?最佳适应算法是一种可变分区存储管理中的内存分配策略。

它的基本思想是在每次内存分配时选择最合适的空闲区域。

具体来说,它从可用的空闲区域中选择大小与需要分配给进程的内存最接近的区域。

二、算法实现思路最佳适应算法实现的关键是如何快速找到最合适的空闲区域。

下面给出一个模拟实现的思路:1. 初始化内存分区列表,首先将整个内存定义为一个大的空闲区域。

2. 当一个进程请求分配内存时,从列表中找到与所需内存最接近的空闲区域。

3. 将该空闲区域分割成两部分,一部分分配给进程,并将该部分标记为已分配,另一部分留作新的空闲区域。

4. 更新内存分区列表。

5. 当一个进程释放内存时,将其所占用的内存区域标记为空闲,然后尝试合并相邻的空闲区域。

三、算法模拟实现下面是一个简单的Python代码实现最佳适应算法:pythonclass MemoryPartition:def __init__(self, start_addr, end_addr, is_allocated=False): self.start_addr = start_addrself.end_addr = end_addrself.is_allocated = is_allocatedclass MemoryManager:def __init__(self, total_memory):self.total_memory = total_memoryself.partition_list = [MemoryPartition(0, total_memory)]def allocate_memory(self, process_size):best_fit_partition = Nonesmallest_size = float('inf')# 找到最佳适应的空闲区域for partition in self.partition_list:if not partition.is_allocated and partition.end_addr - partition.start_addr >= process_size:if partition.end_addr - partition.start_addr < smallest_size:best_fit_partition = partitionsmallest_size = partition.end_addr - partition.start_addrif best_fit_partition:# 将空闲区域分割,并标记为已分配new_partition =MemoryPartition(best_fit_partition.start_addr,best_fit_partition.start_addr + process_size, True)best_fit_partition.start_addr += process_sizeself.partition_list.append(new_partition)return new_partition.start_addr,new_partition.end_addrelse:return -1, -1def deallocate_memory(self, start_addr, end_addr):for partition in self.partition_list:if partition.start_addr == end_addr and not partition.is_allocated:# 标记空闲区域partition.is_allocated = False# 尝试合并相邻空闲区域for next_partition in self.partition_list:if not next_partition.is_allocated andnext_partition.start_addr == end_addr:end_addr = next_partition.end_addrself.partition_list.remove(next_partition)breakelse:breakdef print_partitions(self):for partition in self.partition_list:if partition.is_allocated:print(f"Allocated Partition: {partition.start_addr} - {partition.end_addr}")else:print(f"Free Partition: {partition.start_addr} - {partition.end_addr}")# 测试最佳适应算法if __name__ == "__main__":mm = MemoryManager(1024)start, end = mm.allocate_memory(256)print(f"Allocated memory: {start} - {end}")mm.print_partitions()mm.deallocate_memory(start, end)print("Memory deallocated:")mm.print_partitions()以上代码实现了一个简单的内存管理器类`MemoryManager`,它具有`allocate_memory`和`deallocate_memory`等方法。

可变分区存储管理方式的内存分配和回收

可变分区存储管理方式的内存分配和回收

free_quantity++; fscanf(文件指针,格式字符串,输入表列);}return 1;}return 0;}void sort(){int i,j,p;for(i=0;i<free_quantity-1;i++){p=i;for(j=i+1;j<free_quantity;j++){if(frees[j].address<frees[p].address){p=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}void view(){int i;cout<<endl<<"mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"<< endl;cout<<"输出空闲区表:\n起始地址分区长度状态\n"<<endl;for(i=0;i<free_quantity;i++){(2);(12);cout<<frees[i].address;(10);cout<<frees[i].length;(8);cout<<frees[i].tag<<endl;}cout<<endl<<"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"< <endl;cout<<"输出已分分区表:\n起始地址分区长度占用作业名\n"<<endl;for(i=0;i<occupy_quantity;i++){(2);(12);cout<<occupys[i].address;(10);cout<<occupys[i].length;(8);cout<<occupys[i].tag<<endl;}}void ear(){char job_name[10];int job_length;int i,j,flag,t;cout<<"请输入分配内存的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){ ength>=job_length){flag=1;}}if(flag==0){ ength>=job_length){ddress=frees[i].address; ag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].address+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}void reclaim()ag,job_name)){flag=i;address=occupys[i].address;length=occupys[i].length;}}if(flag==-1){ ddress+frees[i].length)==address){if(((i+1)<free_quantity)&&(frees[i+1].address==address+length)){frees[i].length=frees[i].length+frees[i+1].length+length;for(j=i+1;j<free_quantity;j++){frees[j]=frees[j+1];}free_quantity--;p=1;}else{frees[i].length+=length;p=1;}}if(frees[i].address==(address+length)){frees[i].address=address;frees[i].length+=length;p=1;}}if(p==0){frees[free_quantity].address=address;frees[free_quantity].length=length;free_quantity++;}ddress=-1;ength=0;strcpy(frees[i].tag,"free");occupys[i].address=-1;ength=0;strcpy(occupys[i].tag,"");}free_quantity=0;occupy_quantity=0;flag=read();while(flag==1){sort();cout<<"选择功能项: (0-退出,1-分配内存,2-回收内存,3-显示内存)\n"<<endl;cout<<"选择功项(0-3):";cin>>chioce;switch(chioce){case 0:flag=0;break;case 1:ear();break;case 2:reclaim();break;case 3:view();break;default:cout<<"没有该选项\n"<<endl;}}}。

可变式分区分配算法

可变式分区分配算法

可变式分区分配算法
1.算法思想
可变式分区分配算法的核心思想是按需分配内存空间。

当一个作业需要被加载到内存中时,系统会根据作业的大小,在空闲内存空间中寻找一个合适的分区进行分配。

为了找到合适的分区,系统会按照分区的大小进行排序,然后从小到大或从大到小的顺序遍历分区表,直到找到一个足够大的分区。

分区分配完成后,系统会将剩余的空闲内存空间再次进一步划分为分区。

2.算法步骤
(1)初始化内存空间,将整个内存空间划分成一个初始的大分区,将其添加到分区表中;
(2)当一个作业需要被加载到内存时,系统遍历分区表,选择一个足够大的分区进行分配;
(3)如果找到了一个足够大的分区,则将作业加载到该分区,并更新分区表;
(4)如果没有足够大的分区,则进行内存紧缩操作,为新作业腾出足够大的内存空间,并将其加载到该分区中;
(5)更新分区表,将剩余的空闲内存空间继续划分为一个或多个新的分区;
(6)重复步骤2~5,直到所有作业都被加载到内存中。

3.算法优缺点
然而,可变式分区分配算法也存在一些缺点。

首先,它需要频繁地进行内存分配和释放操作,导致内存分配时间较长。

其次,由于分区的大小不固定,可能会出现外部碎片问题。

此外,可变式分区分配算法还会引入一定的开销,包括分区表和分区管理等。

总结起来,可变式分区分配算法能够灵活地为作业分配合适的内存空间,有效地利用内存资源。

然而,它也存在一些问题,如内存分配时间较长和可能出现的外部碎片问题。

在实际应用中,可以根据具体情况选择合适的存储管理算法,达到更好的性能和效果。

实验三 可变分区存储管理

实验三    可变分区存储管理

实验三可变分区存储管理一、实验目的通过可变分区存储模拟系统,掌握可变分区存储管理的基本原理,分区的分配与回收过程。

二、实验原理1.动态分区分配:是根据进程的实际需求,动态地为之分配内存空间在连续分配方式中,必须把一个系统或用户程序装入一连续的内存空间。

如果在系统中只有若干小的分区,即使它们容量的总和大于要装入的程序,但由于这些分区不相邻接,也无法把改程序装入内存。

2.紧凑:通过移动内存中作业的位置,以把原来多个分散的小分区拼接成一个大分区的方法。

三、实验内容与步骤1.打开程序,所得程序界面窗口如图3-1:图3-12.首先选择算法:是否使用搬家算法,可以通过界面上的按钮或算法菜单栏进行选择;如果不先选择算法,其他功能将被隐藏;注意:在程序执行过程中,不可以重新选择算法。

3.进行初始化:设置内存大小,可以选择默认值400KB;确定内存大小前,其他操作将被屏蔽。

4.初始化内存大小以后,就可以进行添加进程操作。

5.添加一个进程后,撤消进程功能被激活,可以撤消一个选定的进程或所有的进程(图3-2)图3-26.查询功能:可以通过按钮或菜单栏显示内存状态图形、空闲区图表,还可以在内存状态条里闪烁显示某一在空闲区图表选中的空闲区。

7.内存不足但经过搬家算法可以分配内存空间给进程,将有如下(图3-3)提示:图3-38.内存空间不足也有相应提示。

9.重置或退出。

四、实验结果第一组数据:内存大小300K,三个进程分配情况为:60K,50K,80K,不采用搬家算法第二组数据:内存大小500K,五个进程分配情况为:60K,80K,20K,70K,300K,不采用搬家算法第三组数据:内存大小400K,6个进程分配情况为:30K,90K,20K,50K,70K,80K,分配好以后删除第三个,第五个进程,再为第七个进程分配100K,不采用搬家算法第四组数据:内存大小300K,三个进程分配情况为:60K,50K,80K,采用搬家算法第五组数据:内存大小500K,五个进程分配情况为:60K,80K,20K,70K,300K,采用搬家算法第六组数据:内存大小400K,6个进程分配情况为:30K,90K,20K,50K,70K,80K,分配好以后删除第三个,第五个进程,再为第七个进程分配100K,采用搬家算法第七组数据大家自行设计,不采用搬家算法,但不能全部分配第八组数据与第七组数据相同,但采用搬家算法后可以全部分配。

可变分区存储管理方式的最先适应分配算法设计与实现

可变分区存储管理方式的最先适应分配算法设计与实现

可变分区存储管理方式的最先适应分配算法设计与实现一、引言可变分区存储管理方式是操作系统中一种常用的内存分配策略,它能够高效地管理内存空间,提高计算机系统的内存利用率。

而最先适应分配算法作为可变分区存储管理方式的一种重要实现方式,被广泛应用于操作系统中。

本文将围绕任务主题,从算法设计与实现的角度,对最先适应算法进行全面、详细、完整且深入地探讨。

二、最先适应分配算法概述最先适应分配算法是一种基于可变分区存储管理方式的内存分配算法。

其核心思想是从内存空闲区域中找到第一个大小能够满足作业需求的分区进行分配。

具体步骤如下: 1. 从内存区域起始地址开始顺序查找,找到第一个大小能够满足作业需求的空闲区域。

2. 如果找到了满足需求的空闲区域,则将作业分配到该分区,并对其进行划分。

若剩余空间大于一个最小分区大小,将剩余空闲区域插入到空闲区链表中。

3. 如果找不到满足需求的空闲区域,则内存空间不足,需等待释放空间后进行分配。

三、最先适应分配算法的设计与实现最先适应分配算法的设计主要涉及以下几个关键步骤:空闲区管理、作业分配和释放空间等。

下面将分别进行详细介绍。

3.1 空闲区管理在最先适应分配算法中,空闲区的管理与分配密切相关。

通常采用链表的形式来管理空闲区,每个节点记录该空闲区的起始地址和大小。

在作业分配时,需要遍历链表找到第一个满足要求的空闲区进行分配。

在释放空间时,需要将释放的空间节点加入链表并进行合并操作,以减少碎片化问题。

3.2 作业分配作业分配是最先适应分配算法中的核心操作,其实现步骤如下: 1. 获取作业的大小。

2. 遍历空闲区链表,找到第一个大小能够满足作业需求的空闲区。

3. 如果找到了合适的空闲区,则进行分配。

将该空闲区划分为已分配区域和剩余空闲区域。

如果剩余空闲区域大小大于最小分区大小,将其插入到空闲区链表中。

4. 如果找不到满足作业需求的空闲区,则内存空间不足,需等待释放空间后进行分配。

可变分区存储管理方式的内存分配和回收教程文件

可变分区存储管理方式的内存分配和回收教程文件
if((frees[i].address+frees[i].length)==address){
typedef struct node{
int address;
int length;
char tag[10];
}job;
job frees[MJ];
int free_quantity;
job occupys[MJ];
int occupy_quantity;
int read()
{
FILE *fp;
char fn[10];
}
cout<<endl<<"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"<<endl;
cout<<"输出已分分区表:\n起始地址分区长度占用作业名\n"<<endl;
for(i=0;i<occupy_quantity;i++){
int job_length;
int i,j,flag,t;
cout<<"请输入分配内存的作业名和空间大小:";
cin>>job_name;
cin>>job_length;
flag=0;
for(i=0;i<free_quantity;i++){ //寻找空间大于作业的空闲区登记项
if(frees[i].length>=job_length){
strcpy(occupys[occupy_quantity].tag,job_name);

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收内存管理是操作系统中非常重要的一个功能,它负责管理计算机内存资源的分配和回收。

内存分配是指在程序运行时,为进程分配适当大小的内存空间;内存回收是指当进程终止或不再需要分配的内存时,将它们释放回系统。

可变分区存储管理方式是一种常用的内存管理方式,它的特点是将内存分为若干个可变大小的分区。

下面将详细介绍可变分区存储管理方式的内存分配和回收。

一、内存分配:1. 首次适应算法(First Fit):从起始地址开始查找第一个满足分配要求的可用分区,分配其中一部分给进程,并将剩余部分作为新的可用分区。

2. 循环首次适应算法(Next Fit):与首次适应算法类似,但是从上一次分配的位置开始查找。

3. 最佳适应算法(Best Fit):在所有可用分区中找到最小且能满足分配要求的分区进行分配。

4. 最坏适应算法(Worst Fit):在所有可用分区中找到最大的空闲分区进行分配。

这种方法可能会造成大量外部碎片,但可以更好地支持大型进程。

二、内存回收:1.碎片整理:在每次回收内存时,可以通过将相邻的空闲分区合并为一个更大的分区来减少外部碎片。

这种方法需要考虑如何高效地查找相邻分区和合并它们。

2.分区分割:当一个进程释放内存时,生成的空闲分区可以进一步划分为更小的分区,并将其中一部分分配给新进程。

这样可以更好地利用内存空间,但会增加内存分配时的开销。

3.最佳合并:在每次回收内存时,可以选择将相邻的空闲分区按照最佳方式合并,以减少外部碎片。

4.分区回收:当一个进程终止时,可以将其所占用的分区标记为可用,以便其他进程使用。

三、优化技术:1.预分配内存池:为了避免频繁的内存分配和回收,可以预分配一定数量的内存作为内存池,由进程从内存池中直接分配和回收内存。

2.内存压缩:当内存不足时,可以通过将一部分进程的内存内容移动到磁盘等外部存储器中,释放出一定的内存空间。

3.页面替换算法:在虚拟内存系统中,当物理内存不足时使用页面替换算法,将不常用的页面淘汰出物理内存,以便为新页面分配内存。

实验4 可变分区的内存分配算法

实验4 可变分区的内存分配算法

实验4可变分区的内存分配算法模拟1.实验目的通过模拟可变分区的以下内存分配算法,掌握连续分配存储器管理的特点,掌握以下四种分配算法的优缺点并进行对比。

(1)首次适应分配算法;(2)循环适应分配算法;(3)最佳适应分配算法;(4)最坏适应分配算法。

2.实验环境装有操作系统WindowsXP和开发工具VC++6.0,内存在256M以上的微机;或者:装有Linux(Fedora7)操作系统和gcc编译器,内存在256M以上的微机。

3.实验内容(1)用户可用的内存空间为64K,按下面的现有分区情况进行初始化,可在屏幕上显示(2)接收用户进程的内存申请格式为:作业名、申请空间的大小。

按照上述的一种分配算法进行分配,修改空闲分区表,并在屏幕上显示分配后的内存状态。

(3)用户进程执行完成后,或者从外部撤销用户进程,将内存进行回收,修改空闲分区表,并在屏幕上显示回收后的内存状态。

4.实验要求(1)将四种算法的源程序及程序执行结果写入实验报告;(2)将四种算法的工作机理写入实验报告。

代码:#include<iostream.h>#include<stdlib.h>#defineFree0//空闲状态#defineBusy1//已用状态#defineOK1//完成#defineERROR0//出错#defineMAX_length64〃最大内存空间为64KBtypedefintStatus;intflag;typedefstructfreearea//定义一个空闲区说明表结构{longsize;//分区大小longaddress;//分区地址intstate;//状态}ElemType;//线性表的双向链表存储结构typedefstructDuLNode{ElemTypedata;structDuLNode*prior;//前趋指针structDuLNode*next;//后继指针}DuLNode,*DuLinkList;DuLinkListblock_first;//头结点DuLinkListblock_last;//尾结点Statusalloc(int);//内存分配Statusfree(int);//内存回收Status尸1凤_行均位);//首次适应算法StatusBest_fit(int);//最佳适应算法StatusWorst_fit(int);//最差适应算法voidshow();//查看分配StatusInitblock();//开创空间表StatusInitblock()//开创带头结点的内存空间链表{block_first=(DuLinkList)malloc(sizeof(DuLNode));block_last=(DuLinkList)malloc(sizeof(DuLNode));block_first->prior=NULL;block_first->next=block_last;block_last->prior=block_first;block_last->next=NULL;block_last->data.address=0;block_last->data.size=MAX_length;block_last->data.state=Free;returnOK;}//分配主存Statusalloc(intch){intrequest=0;cout<<”请输入需要分配的主存大小(单位:KB):”;cin>>request;if(request<0||request==0){cout<<"分配大小不合适,请重试!"<<endl;returnERROR;}if(ch==2)//选择最佳适应算法{if(Best_fit(request)==OK)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;returnOK;}if(ch==3)//选择最差适应算法{if(Worst_fit(request)==OK)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;returnOK;}else//默认首次适应算法{if(First_fit(request)==OK)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;returnOK;}}//首次适应算法StatusFirst_fit(intrequest){//为申请作业开辟新空间且初始化DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode*p=block_first->next;while(p){if(p->data.state==Free&&p->data.size==request){//有大小恰好合适的空闲块p->data.state=Busy;returnOK;break;}if(p->data.state==Free&&p->data.size>request){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.size;p->data.size-=request;returnOK;break;}p=p->next;}returnERROR;}//最佳适应算法StatusBest_fit(intrequest){intch;//记录最小剩余空间DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode*p=block_first->next;DuLNode*q=NULL;//记录最佳插入位置while(p)//初始化最小空间和最佳位置{if(p->data.state==Free&&(p->data.size>=request)){if(q==NULL){q=p;ch=p->data.size-request;}elseif(q->data.size>p->data.size){q=p;ch=p->data.size-request;}}p=p->next;}if(q==NULL)returnERROR;//没有找到空闲块elseif(q->data.size==request) {q->data.state=Busy;returnOK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.size=ch;returnOK;}returnOK;}//最差适应算法StatusWorst_fit(intrequest){intch;//记录最大剩余空间DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode*p=block_first->next;DuLNode*q=NULL;//记录最佳插入位置while(p)//初始化最大空间和最佳位置{if(p->data.state==Free&&(p->data.size>=request)){if(q==NULL){q=p;ch=p->data.size-request;}elseif(q->data.size<p->data.size){q=p;ch=p->data.size-request;}}p=p->next;}if(q==NULL)returnERROR;//没有找到空闲块elseif(q->data.size==request){q->data.state=Busy;returnOK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.size=ch;returnOK;}returnOK;}//主存回收Statusfree(intflag){DuLNode*p=block_first;for(inti=0;i<=flag;i++)if(p!=NULL)p=p->next;elsereturnERROR;p->data.state=Free;if(p->prior!=block_first&&p->prior->data.state==Free)〃与前面的空闲块相连( p->prior->data.size+=p->data.size;p->prior->next=p->next;p->next->prior=p->prior;p=p->prior;}if(p->next!=block_last&&p->next->data.state==Free)//与后面的空闲块相连(p->data.size+=p->next->data.size;p->next->next->prior=p;p->next=p->next->next;}if(p->next==block_last&&p->next->data.state==Free)//与最后的空闲块相连(p->data.size+=p->next->data.size;p->next=NULL;}returnOK;}//显示主存分配情况voidshow()(intflag=0;cout<<"\n主存分配情况:\n";cout<<"++++++++++++++++++++++++++++++++++++++++++++++\n\n";DuLNode*p=block_first->next;cout<<"分区号\t起始地址\t分区大小\t状态\n\n”;while(p)(cout<<""<<flag++<<"\t";cout<<""<<p->data.address<<"\t\t";cout<<""<<p->data.size<<"KB\t\t";if(p->data.state==Free)cout<<"空闲\n\n";elsecout<<"已分配\n\n";p=p->next;cout«"++++++++++++++++++++++++++++++++++++++++++++++\n\rT;〃主函数voidmain()(intch;〃算法选择标记coukv”请输入所使用的内存分配算法:\n";cout<<”⑴首次适应算法\n⑵最佳适应算法\n⑶最差适应算法\n”;cin»ch;while(ch<l||ch>3)(cout<<“输入错误,请重新输入所使用的内存分配算法:\n";cin»ch;}lnitblock();〃开仓1J空间表intchoice;〃操作选择标记while(l)(show();coukv"请输入您的操作:";cout«"\nl:分配内存\n2:回收内存\n0:退出\rT;cin»choice;if(choice==l)alloc(ch);//分配内存elseif(choice==2)//内存回收(intflag;cout<<”请输入您要释放的分区号:”;cin»flag;free(flag);}elseif(choice==0)break;〃退出else〃输入操作有误(coutvv'1输入有误,请重试!"vvendl;continue;结果:首次适应算法(FirstFit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。

可变分区分配算法

可变分区分配算法

可变分区分配算法
可变分区分配算法是一种内存管理技术,用于将可用的内存空间分配给进程。

这种算法允许进程使用不同大小的内存块,并且可以在运行时动态地改变它们的大小。

可变分区分配算法通常使用两种不同的数据结构来管理内存:空闲块列表和已分配块列表。

空闲块列表包含所有未被占用的内存块,而已分配块列表则包含所有已被占用的内存块。

当一个进程需要内存时,操作系统会从空闲块列表中选择一个足够大的未被占用的内存块,并将其标记为已被占用。

如果没有足够大的空闲块,则操作系统会将多个小的空闲块合并成一个大的空闲块,然后再进行分配。

当一个进程释放了它所使用的内存时,该内存块会被标记为空闲,并添加到空闲块列表中。

如果相邻的两个空闲块可以合并成一个更大的空闲块,则操作系统会执行合并操作以减少碎片化。

可变分区分配算法有多种实现方式,其中最常见的是首次适应算法、最佳适应算法和最差适应算法。

首次适应算法是一种简单的可变分区分配算法,它从空闲块列表的开头开始查找,找到第一个足够大的空闲块并将其分配给进程。

这种算法的优点是实现简单,但会导致碎片化问题。

最佳适应算法是一种更高级的可变分区分配算法,它从空闲块列表中查找最小的足够大的空闲块并将其分配给进程。

这种算法可以减少碎片化问题,但需要更多的计算资源。

最差适应算法与最佳适应算法相反,它选择最大的足够大的空闲块并将其分配给进程。

这种算法可以减少外部碎片问题,但会导致内部碎片问题。

总之,可变分区分配算法是一种重要的内存管理技术,它可以提高系统性能和资源利用率。

不同的实现方式有不同的优缺点,在选择时需要根据具体情况进行权衡。

可变分区存储管理方案中的内存分配

可变分区存储管理方案中的内存分配

/*(二)可变分区存储管理方案中的内存分配可变分区调度算法有:最先适应分配算法,最优适应分配算法,最坏适应算法用户提出内存空间的申请;系统根据申请者的要求,按照一定的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者;当程序执行完毕或主动归还内存资源时,系统要收回它所占用的内存空间或它归还的部分内存空间。

1.程序运行时首先接收输入:空闲区数据文件,包括若干行,每行有两个数据项:起始地址、长度(均为整数),各数据项以space隔开。

2.建立空闲区表并在屏幕上显示输出空闲区表内容,空闲区表中记录了内存中可供分配的空闲区的始址和长度,用标志位指出该分区是否是未分配的空闲区。

3.从用户界面根据用户提示接收一个内存申请,格式为:作业名、申请空间的大小。

4.按照最差(最坏)适配算法选择一个空闲区,分割并分配,修改相应的数据结构(空闲区表),填写内存已分配区表(起始地址、长度、标志位),其中标志位的一个作用是指出该区域分配给哪个作业。

5.重复3、4,直到输入为特殊字符(0)。

6.在屏幕上显示输出新的空闲区表和已分配区表的内容。

本程序包括:FIFO,最优适应分配算法,最坏适应算法input file:freememory.txtdata:10 1530 550 2080 12120 25160 18200 8VC++调试通过*/#include <stdio.h>#include <string.h>#include <iostream.h>#include <iomanip.h>const int MAXJOB=100;//定义表最大记录数typedef struct node{int start;int length;char tag[20];}job;job frees[MAXJOB];//定义空闲区表int free_quantiry;//空闲区域的个数job occupys[MAXJOB];//定义已分配区表int occupy_quanity;//初始化函数void initial(){int i;for (i=0;i<MAXJOB;i++){frees[i].start=-1;frees[i].length=0;strcpy(frees[i].tag,"free");occupys[i].start=-1;occupys[i].length=0;strcpy(occupys[i].tag,"");}free_quantiry=0;occupy_quanity=0;}//读数据函数int readData(){FILE *fp;char fname[20];cout<<"请输入初始空闲表文件名:"<<endl;cin>>fname;if ((fp=fopen(fname,"r"))==NULL){cout<<"错误,文件打不开,请检查文件名"<<endl;}else{while(!feof(fp)){fscanf(fp,"%d %d",&frees[free_quantiry].start,&frees[free_quantiry].length);free_quantiry++;}return 1;}return 0;}//sortvoid sort()//按空闲区起始地址排序{int i,j,p;for (i=0;i<free_quantiry;i++){p=i;for (j=i+1;j<free_quantiry;j++){if (frees[j].start<frees[p].start){p=j;}}if (p!=i){frees[free_quantiry]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantiry];}}}//显示函数void view(){int i;cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前空闲表:"<<endl;cout<<"起始地址长度状态"<<endl;for(i=0;i<free_quantiry;i++){cout.setf(2);cout.width(12);cout<<frees[i].start;cout.width(10);cout<<frees[i].length;cout.width(8);cout<<frees[i].tag<<endl;}cout<<endl<<"-----------------------------------------------"<<endl;cout<<"当前已分配表:"<<endl;cout<<"起始地址长度占用作业名"<<endl;for (i=0;i<occupy_quanity;i++){cout.setf(2);cout.width(12);cout<<occupys[i].start;cout.width(10);cout<<occupys[i].length;cout.width(8);cout<<occupys[i].tag<<endl;}}//最优适应分配算法void best_fit(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:"<<endl;cin>>job_name;cin>>job_length;flag=0;for (i=0;i<free_quantiry;i++){if (frees[i].length>=job_length){flag=1;}}if (flag==0){cout<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl; }else{t=0;i=0;while(t==0){if (frees[i].length>=job_length){t=1;}i++;}i--;for (j=0;j<free_quantiry;j++){if ((frees[j].length>=job_length)&&frees[j].length<frees[i].length){i=j;}}occupys[occupy_quanity].start=frees[i].start;strcpy(occupys[occupy_quanity].tag,job_name);occupys[occupy_quanity].length=job_length;occupy_quanity++;if (frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length;}else{for (j=i;j<free_quantiry-1;j++){frees[j]=frees[j+1];}free_quantiry--;cout<<"内存分配成功"<<endl;}}}//撤销作业void finished(){char job_name[20];int i,j,flag,p=0;int start;int length;cout<<"请输入要撤销的作业名:"<<endl;cin>>job_name;flag=-1;for (i=0;i<occupy_quanity;i++){if (!strcmp(occupys[i].tag,job_name)){flag=i;start=occupys[i].start;length=occupys[i].length;}}if (flag==-1){cout<<"没有这个作业"<<endl;}else{for (i=0;i<free_quantiry;i++){if ((frees[i].start+frees[i].length)==start){if (((i+1)<free_quantiry)&&(frees[i+1].start==start+length)){frees[i].length=frees[i].length+frees[i+1].length;for (j=i+1;j<free_quantiry;j++){frees[j]=frees[j+1];}free_quantiry--;p=1;}else{frees[i].length+=length;p=1;}}if (frees[i].start==(start+length)){frees[i].start=start;frees[i].length+=length;p=1;}}if (p==0){frees[free_quantiry].start=start;frees[free_quantiry].length=length;free_quantiry++;}for (i=flag;i<occupy_quanity;i++){occupys[i]=occupys[i+1];}occupy_quanity--;}}//显示版权信息函数void version(){cout<<endl<<endl;cout<<" ┏━━━━━━━━━━━━━━━━━━━━━━━┓"<<endl;cout<<" ┃可变分区存储管理方案中的内存分配┃"<<endl;cout<<" ┠───────────────────────┨"<<endl;cout<<" ┃siqingyang ┃"<<endl;cout<<" ┃version 2011 build 0520┃"<<endl;cout<<" ┗━━━━━━━━━━━━━━━━━━━━━━━┛"<<endl;cout<<endl<<endl;}void main(){int flag=0;int t=1;int chioce=0;version();initial();flag=readData();view();while(flag==1){sort();cout<<endl<<endl<<"================================================== ======="<<endl;cout<<" 可变分区存储管理模拟系统"<<endl;cout<<"========================================================="<<e ndl;cout<<" 1.best fit申请空间2.撤消作业0.退出"<<endl;cout<<"请选择:";cin>>chioce;switch(chioce){case 1:best_fit();view();break;case 2:finished();view();break;case 0:flag=0;break;default:cout<<"选择错误!"<<endl;}}}。

存储管理分区分配算法

存储管理分区分配算法

存储管理分区分配算法存储管理是操作系统中的重要组成部分,其任务是有效地管理计算机系统的存储空间。

在内存中,存储空间分为若干个分区,每个分区可以用来存放一个或多个进程。

存储管理分区分配算法是指操作系统如何将进程分配到可用的存储分区中。

本文将介绍常见的存储管理分区分配算法,包括固定分区分配、动态分区分配和可变分区分配。

固定分区分配算法是最简单的一种分区分配算法,它将内存划分为若干个固定大小的分区。

每个分区可以容纳一个进程,当一个进程需要被加载到内存中时,操作系统会找到一个合适大小的空闲分区,并将进程加载到该分区中。

固定分区分配算法不需要考虑内存碎片问题,但是由于分区大小固定,会导致一些内存空间不能被充分利用。

动态分区分配算法是一种比较灵活的分区分配算法,它将内存划分为若干个变化大小的分区。

当一个进程需要被加载到内存中时,操作系统会找到一个大小合适的空闲分区,并将进程加载到该分区中。

如果内存中没有合适大小的空闲分区,操作系统可以选择进行分区的合并或者分割,以满足进程的需求。

动态分区分配算法可以更好地利用内存空间,但是它需要考虑内存碎片问题。

可变分区分配算法是一种综合了固定分区分配算法和动态分区分配算法的算法。

它可以根据不同的情况选择最合适的分区分配方式。

当内存中有大块空闲分区时,可变分区分配算法可以使用固定分区分配算法,将该分区划分为多个固定大小的小分区,以利用内存空间;当内存中只有少量小块空闲分区时,可变分区分配算法可以使用动态分区分配算法,充分利用内存碎片。

可变分区分配算法可以在固定分区分配算法和动态分区分配算法之间取得一个平衡。

综上所述,存储管理分区分配算法有固定分区分配、动态分区分配和可变分区分配三种。

不同的算法适用于不同的场景,需要根据具体情况选择最合适的算法。

固定分区分配算法适用于空间布局比较确定的情况;动态分区分配算法适用于分区大小变化比较大的情况;可变分区分配算法适用于两种情况之间的平衡。

可变分区存储管理的内存分配与回收

可变分区存储管理的内存分配与回收

操作系统课程设计课程名称操作系统题目名称可变分区存储管理的内存分配与回收专业班级 10计算机科学与技术(2)班学生姓名魏华明俞临曲赵天择张永鹏周田学号 36 45 56 54 57评级:A:周田B:赵天择俞临曲魏华明张永鹏目录一、摘要 (3)1.1课程设计的目的 (3)1.2实验要求 (3)1.3预备知识 (3)1.4任务分配 (3)二、设计思路 (4)三、主要数据结构 (5)3.1全局变量 (5)3.2空闲分区表的定义 (5)3.3已分配分区表的定义 (5)3.4动态输入构造空闲区表 (5)3.5分配内存 (6)3.6对空闲区排序 (7)3.7回收内存 (7)四、部分程序流程图 (9)4.1申请内存空间 (9)4.2回收内存 (9)五、程序运行截图 (12)5.1首次适应算法 (12)5.1.1 动态输入构造空闲区表 (12)5.1.2 分配内存 (12)5.1.3 回收内存 (13)5.2最佳适应算法 (14)5.2.1 动态输入构造空闲区表 (14)5.2.2 分配内存 (14)5.2.3 回收内存 (16)六、源程序 (17)6.1首次适应算法 (17)6.2最佳适应算法 (22)七、心得体会 (28)一、摘要1.1 课程设计的目的深入了解采用可变分区存储管理方式的内存分配回收的实现。

1.2实验要求(1)内存分配采用首次适应算法与最佳适应算法分别完成。

(2)动态输入构造空闲区表,并显示构造好的空闲区表。

(提示:在两种不同的内存分配算法中,空闲区在空闲区表中的登记顺序是不一样的)(3)键盘接收内存申请尺寸大小。

(4)根据申请,实施内存分配,并返回分配所得内存首址。

(5)分配完后,调整空闲区表(即扣除分配部分),并显示调整后的空闲区表。

(6)若分配失败,返回分配失败信息。

(7)内存回收根据空闲区表,按内存回收的四种情况从键盘接收回收区域的内存首址与大小;回收区域,调整空闲区表(与前面空闲区相连,与后面空闲区相连,与前后空闲区相连则合并,与前后空闲区都不相连则插入该项),并显示调整后的空闲区表。

可变分区存储管理方式的内存分配和回收实验报告

可变分区存储管理方式的内存分配和回收实验报告

可变分区存储管理方式的内存分配和回收实验报告【实验报告】一、实验目的了解可变分区存储管理方式的内存分配和回收过程,了解最优算法的原理和实现方法,掌握最优算法在可变分区存储管理方式下的内存分配和回收操作。

二、实验原理最优算法的分配过程如下:1.初始化内存分区表,将整个内存分为一个未分配的分区。

2.当有新的进程请求内存时,遍历内存分区表,选择满足分配条件且剩余空间最小的分区进行分配。

3.更新分区表中相应分区的空闲空间,并将分配出去的空间标记为已分配。

最优算法的回收过程如下:1.当一些进程结束或释放内存时,遍历分区表,找到对应的已分配分区。

2.将该分区标记为空闲,并进行合并操作,合并相邻的空闲分区。

3.更新分区表。

三、实验步骤1.初始化内存分区表,将整个内存设为一个未分配的分区。

2.依次输入若干个进程的大小。

3.按照最优算法进行内存分配和回收。

4.输出每个进程分配的内存空间和内存分区表的状态。

四、实验结果与分析输入进程大小为:{100KB,200KB,50KB,150KB}初始内存分区表:{未分配,800KB}进程1申请100KB,满足分配条件的最小剩余空间为300KB,分配给进程1后,更新分区表:分配给进程1的内存:{100KB}更新后的内存分区表:{已分配,未分配,700KB}进程2申请200KB,满足分配条件的最小剩余空间为300KB,分配给进程2后,更新分区表:分配给进程2的内存:{200KB}更新后的内存分区表:{已分配,已分配,未分配,500KB}进程3申请50KB,满足分配条件的最小剩余空间为150KB,分配给进程3后,更新分区表:分配给进程3的内存:{50KB}更新后的内存分区表:{已分配,已分配,已分配,未分配,450KB}进程4申请150KB,满足分配条件的最小剩余空间为150KB,分配给进程4后,更新分区表:分配给进程4的内存:{150KB}更新后的内存分区表:{已分配,已分配,已分配,已分配,未分配,300KB}进程2结束,释放内存,回收进程2占用的空间,更新分区表:释放进程2的内存:{200KB}合并空闲分区后的内存分区表:{已分配,已分配,未分配,300KB}进程3结束,释放内存,回收进程3占用的空间,更新分区表:释放进程3的内存:{50KB}合并空闲分区后的内存分区表:{已分配,未分配,300KB}进程1结束,释放内存,回收进程1占用的空间,更新分区表:释放进程1的内存:{100KB}合并空闲分区后的内存分区表:{未分配,400KB}进程4结束,释放内存,回收进程4占用的空间,更新分区表:释放进程4的内存:{150KB}合并空闲分区后的内存分区表:{未分配,550KB}五、实验总结通过本次实验,我对可变分区存储管理方式的内存分配和回收过程有了更深入的了解。

可变分区存储管理方案中的内存分配

可变分区存储管理方案中的内存分配

可变分区存储管理方案中的内存分配在可变分区存储管理方案中,内存的分配主要包含以下几个步骤:1.内存空间划分首先,操作系统将所有物理内存划分为不同大小的分区,每个分区具有唯一的标识符,用来指示该分区的起始地址和大小。

2.分区分配在程序请求内存时,操作系统会根据其内存需求的大小,为其分配相应大小的分区。

可变分区存储管理方案中,对于分配请求,有三种基本分配策略:首次适应、循环首次适应和最佳适应。

- 首次适应(First Fit):从内存空闲分区链中查找第一个满足要求的分区进行分配。

- 循环首次适应(Next Fit):从上次分配的位置继续查找第一个满足要求的分区进行分配。

- 最佳适应(Best Fit):从内存空闲分区链中查找能够最小程度满足要求的分区进行分配。

3.分区合并与回收当进程终止或释放内存时,操作系统会将相应的分区标记为可用,然后进行分区合并与回收。

分区合并是指将相邻的空闲分区合并为一个更大的分区,以提供更大的连续内存空间。

回收是指将被释放的分区添加到内存空闲分区链中,以供后续的内存分配请求使用。

4.碎片整理在连续进行分配和释放操作后,内存空闲分区链可能产生内部碎片和外部碎片。

内部碎片是指分配给进程的内存空间超过其所需的大小,而外部碎片是指分配给进程之间的多个空闲分区无法满足一些较大分区的请求。

为了减少碎片的数量和大小,操作系统可以进行碎片整理操作,将零散的空闲分区重新组合为一个或多个更大的分区,以提供更大的连续内存空间。

总的来说,可变分区存储管理方案通过灵活地将内存空间划分为可变大小的分区,并采用不同的分配策略进行内存分配,以满足各个进程的内存需求。

同时,通过回收和合并空闲分区及进行碎片整理,可以最大程度地提高内存资源的利用率。

然而,可变分区存储管理方案需要维护和更新空闲分区链,同时可能会产生内部碎片和外部碎片,因此在设计和实现时需要综合考虑各种因素,以提高内存管理的效率和性能。

操作系统实验报告可变分区存储管理方式的内存分配回收

操作系统实验报告可变分区存储管理方式的内存分配回收

操作系统实验报告可变分区存储管理方式的内存分配回收集团文件发布号:(9816-UATWW-MWUB-WUNN-INNUL-DQQTY-实验三可变分区存储管理方式的内存分配回收一.实验目的(1)深入了解可变分区存储管理方式的内存分配回收的实现。

二.实验内容编写程序完成可变分区存储管理方式的内存分配回收,要求有内存空间分配表,并采用最优适应算法完成内存的分配与回收。

三.实验原理在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。

为了方便主存空间的分配和去配,用于管理的数据结构可由两张表组成:“已分配区表”和“未分配区表”。

在“未分配表中”将空闲区按长度递增顺序排列,当装入新作业时,从未分配区表中挑选一个能满足用户进程要求的最小分区进行分配。

这时从已分配表中找出一个空栏目登记新作业的起始地址和占用长度,同时修改未分配区表中空闲区的长度和起始地址。

当作业撤离时已分配区表中的相应状态变为“空”,而将收回的分区登记到未分配区表中,若有相邻空闲区再将其连接后登记。

可变分区的回收算法较为复杂,当一个作业撤离时,可分为4种情况:其临近都有作业(A和B),其一边有作业(A或B),其两边均为空闲区。

尤其重要的是,在程序中利用“new类型T(初值列表)”申请分配用于存放T类型数据的内存空间,利用“delete指针名”释放指针所指向的内存空间。

四.实验部分源程序#include<iostream>usingnamespacestd;typedefstructSNode{//SpaceNodeintstart,end;//起始,结束intlength;//长度大小structSNode*next;//指向下一结点的指针}*SP;SPHead=(SP)malloc(sizeof(SNode));//全局变量,内存空间头结voidDispSpace(){//显示内存空间分配情况SPp=Head->next;cout<<"\n空闲区说明表\n"<<"---地址--长度---\n";while(p){cout<<""<<p->start<<""<<p->length<<endl;p=p->next;}cout<<"----------------\n";}voidInitial(){//初始化说明表SPp,q;p=(SP)malloc(sizeof(SNode));q=(SP)malloc(sizeof(SNode));p->start=14;p->length=12;p->end=26;q->start=32;q->length=96;q->end=128;//指导书上的作业分配Head->next=p;//与头结点连接p->next=q;q->next=NULL;DispSpace();}voidAllocation(intlen){//分配内存给新作业SPp=Head->next,q;while(p){if(p->length<len)p=p->next;elseif(p->length>len){p->start=p->start+len;p->length=p->length-len;cout<<"分配成功!\n";DispSpace();return;}else{//当两者长度相等q=p->next;p->next=q->next;cout<<"分配成功!\n";DispSpace();return;}}cout<<"分配失败!\n";DispSpace();return;}voidCallBack(intsta,intlen){//回收内存SPp=Head,q=p->next,r;//开始地址和长度p->end=0;inten=sta+len;while(q){if(sta==0){//初始地址为0if(en==q->start){//正好回收q->start=0;q->length=q->end;return;}else{r=(SP)malloc(sizeof(SNode));r->start=sta;r->length=len;r->end=en; p->next=r;r->next=q;return;}}elseif((p->end<sta)&&(q->start>en)){//上邻区r=(SP)malloc(sizeof(SNode));r->start=sta;r->length=len;r->end=en;p->next=r;r->next=q;return;}elseif((p->end<sta)&&(q->start==en)){//邻区相接q->start=sta;q->length=q->end-sta;return;}elseif((p->end==sta)&&(q->start<en)){//下邻区p->end=en;p->length=en-p->start;return;}elseif(p->end==sta&&q->start==en){//邻区相接p->end=q->end;p->length=p->end-p->start;p->next=q->next;return;}else{p=p->next;q=q->next;}}}voidmain(){Initial();cout<<"现在分配大小为6K的作业4申请装入主存:"; Allocation(6);//分配时参数只有长度//--------指导书测试数据演示----------cout<<"现回收作业3(起址10,长度4)\n";CallBack(10,4);DispSpace();cout<<"现回收作业2(起址26,长度6)\n";CallBack(26,6);DispSpace();//---------------演示结束-------------system("pause");}五.实验结果与体会我的体会:。

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收概述内存管理是操作系统中重要的一部分,它负责管理计算机内存的分配和回收。

可变分区存储管理方式是一种常用的内存管理方案,它将内存分为多个不同大小的分区,每个分区可以被分配给一个进程来使用。

本文将介绍可变分区存储管理方式的内存分配和回收过程。

内存分配可变分区存储管理方式的内存分配过程包括空闲分区的选择和分区的划分。

空闲分区的选择在可变分区存储管理方式中,操作系统需要选择一个合适的空闲分区来分配给进程。

常用的空闲分区选择算法有:•首次适应算法(First Fit):从头开始寻找满足进程需要的空闲分区。

•最佳适应算法(Best Fit):从所有满足进程需要的空闲分区中选择大小最接近的一个。

•最差适应算法(Worst Fit):选择能够满足进程需要且最大的空闲分区。

选择合适的空闲分区算法可以提高内存利用率和分配的效率。

分区的划分一旦选择了合适的空闲分区,操作系统需要对该分区进行划分,以满足进程的内存需求。

常用的分区划分方式包括:•等分划分:将空闲分区按照进程的内存需求进行等分划分。

•保留部分划分:只将进程需要的内存大小分配给进程,剩余的空闲分区保留。

分区的划分方式可以根据实际情况选择,以满足不同进程的内存需求。

内存回收可变分区存储管理方式的内存回收过程包括释放分区和合并分区两个步骤。

释放分区当一个进程终止或释放了分配给它的内存分区时,该分区将被标记为空闲,可以被其他进程使用。

合并分区在进行内存回收时,为了提高内存利用率,操作系统通常会进行分区的合并。

合并分区需要考虑到合并后的分区是否满足其他进程的内存需求。

常用的合并分区策略有:•相邻空闲分区合并:将相邻的两个空闲分区合并成一个更大的空闲分区。

•首次适应合并:从头开始寻找空闲分区,如果找到两个相邻的空闲分区,可以将它们合并起来。

通过合并分区,可以减少内存碎片,提高内存的利用率。

可变分区存储管理方式是一种常用的内存管理方案,在内存分配和回收过程中,通过选择合适的空闲分区和分区的划分以及合并分区,可以高效地管理计算机内存,提高内存利用率。

可变分区存储管理方案中的内存分配

可变分区存储管理方案中的内存分配

可变分区存储管理方案中的内存分配可变分区存储管理方案中的内存分配是指将可用的内存空间分割为多个大小不同的分区,并根据进程的需求分配合适大小的分区给进程使用。

在实际的操作系统中,有多种内存分配算法可以用于可变分区存储管理方案,如最佳适应算法、最先适应算法和最差适应算法等。

最佳适应算法是指在分配内存时选择大小与进程需求最接近的分区。

算法的具体步骤如下:1.遍历整个内存空间,查找大小能满足进程需求的最小分区。

2.如果找到匹配的分区,则将该分区标记为已分配,并根据进程需求调整分区大小。

3.如果未找到匹配的分区,则通过合并多个分区或者分割一个大分区来创建一个合适大小的分区。

4.将新分区标记为已分配,并根据进程需求调整分区大小。

最先适应算法是指在分配内存时选择最先满足进程需求的分区。

算法的具体步骤如下:1.从第一个分区开始遍历整个内存空间,查找大小能满足进程需求的分区。

2.如果找到匹配的分区,则将该分区标记为已分配,并根据进程需求调整分区大小。

3.如果未找到匹配的分区,则继续遍历剩余的分区,直到找到合适大小的分区。

4.将新分区标记为已分配,并根据进程需求调整分区大小。

最差适应算法是指在分配内存时选择大小最大的空闲分区。

算法的具体步骤如下:1.遍历整个内存空间,查找大小能满足进程需求的最大分区。

2.如果找到匹配的分区,则将该分区标记为已分配,并根据进程需求调整分区大小。

3.如果未找到匹配的分区,则通过合并多个分区或者分割一个大分区来创建一个合适大小的分区。

4.将新分区标记为已分配,并根据进程需求调整分区大小。

以上三种算法都有各自的优劣势。

最佳适应算法可以最大限度地利用内存空间,但在分配过程中可能需要频繁地合并或分割分区,影响效率。

最先适应算法可以快速分配满足进程需求的分区,但可能会导致内存碎片问题。

最差适应算法可以减少内存碎片问题,但可能导致较大的内存浪费。

为了进一步提高内存分配的效率和性能,还有一些其他的优化或改进方法,例如使用伙伴系统、引入动态分区分配和回收等。

可变分区存储管理方式的内存分配和

可变分区存储管理方式的内存分配和
else
printf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].length,used_table[i].flag);
break;
default:printf("没有该选项\n");
}
}
}
“已分分区表”的结构定义
#define n 10 0”0”1”0”0”1”ength>=xk&&free_table[i].flag==1)if(k==-1||free_table[i].length<free_table[k].length)
k=i;
if(k==-1) ength-xk<=min用来记录空间区和作业占用的区域。
由于可变分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随内存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在内存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收内存分区时,可能会合并空闲分区,这样如果整个内存采用一张表格记录己分分区和空闲区,就会使表格操作繁琐。分配内存时查找空闲区进行分配,然后填写己分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。
{free_table[k].flag=0;
ad=free_table[k].address;
xk=free_table[k].length;
}
else
{free_table[k].length=free_table[k].length-xk;

3-6 可变分区存储管理

3-6 可变分区存储管理
可变分区存储管理
• 按进程的内存需求来动态划分分区 • 创建一个进程时,根据进程所需主存量查看主存中 是否有足够的空闲空间
• 若有,则按需要量分割一个分区 • 若无,则令该进程等待主存资源 • 由于分区大小按照进程实际需要量来确定,因此分 区个数是随机变化的
可变分区方式的内存分配示例
操作系统 4k 作进业程11 10k
• 最优适配算法最容易产生外零头 • 任何适配算法都不能避免产生外零头
移动技术(程序浮动技术)
• 移动分区以解决内存外零头 • 需要动态重定位支撑
操作系统 进程1 空闲区 进程2 空闲区 进程3 空闲区
操作系统 进程1 进程2 进程3
空闲区
操作系统 进程1 进程2 进程3
进程4
空闲区
移动技术的工作流程
空闲区 46k 52k 进程2
空闲区 128k
操作系统
4k 10k 40k
进程1 进程3
46k 空闲区
进程2
52k
空闲区 128k
操作系统
4k 10k 40k
进程1 进程3
空闲区 128k
可变分区方式的主存分配表
• 已分配区表与未分配区表,采用链表
起址 长度
4k 6k 46k 6k
标志ห้องสมุดไป่ตู้
J1 J2 空
作业i请求分配x主存 查主存分配表
无 有大有于x的空
闲区吗?
空闲区总 否 是和x吗?
分配x主存
移动主存中其他分区
作业i等
主存资源
修改主存分配表中 的有关项
修改被移动者的基 址/限长值
修改主存分配 表中的有关项
置进程i的基 址/限长值

起址
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

可变分区存储管理方案中的内存分配用户提出内存空间的申请;系统根据申请者的要求,按照一定的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者;当程序执行完毕或主动归还内存资源时,系统要收回它所占用的内存空间或它归还的部分内存空间。

1.程序运行时首先接收输入:空闲区数据文件,包括若干行,每行有两个数据项:起始地址、长度(均为整数),各数据项以逗号隔开。

2.建立空闲区表并在屏幕上显示输出空闲区表内容,空闲区表中记录了内存中可供分配的空闲区的始址和长度,用标志位指出该分区是否是未分配的空闲区。

3.从用户界面根据用户提示接收一个内存申请,格式为:作业名、申请空间的大小。

4.按照最差(最坏)适配算法选择一个空闲区,分割并分配,修改相应的数据结构(空闲区表),填写内存已分配区表(起始地址、长度、标志位),其中标志位的一个作用是指出该区域分配给哪个作业。

5.重复3、4,直到输入为特殊字符(0)。

6.在屏幕上显示输出新的空闲区表和已分配区表的内容#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX 10struct data1 /*空闲区表*/{int address;int length;int flag;};struct data2 /*已分配区表*/{int address;int length;char name[20];};struct data1 empty[MAX];struct data2 busy[MAX];void initialize( );int read_data( ); /*从文件中读如数据*/void display_empty_table(int); /*显示空闲区表*/void display_busy_table(int); /*显示已分配区表*/void badest_fit( int *,int *,char *name,int s );/*最坏适应算法*/void first_fit( int *,int *,char *name,int s ); /*最先适应算法*/void best_fit( int *,int *,char *name,int s ); /*最佳适应算法*/void main( ){int num1,num2,size; /*num1用于统计空闲表的,num2用于统计分配区表*/ char name[20];num2=0;initialize( ); /*初始花空闲区表和分配区表*/num1=read_data( );if( num1==0 ) /*表示文件中没有数据*/printf("there has no data in empty table\n");printf("the initialial empty table is:\n");display_empty_table( num1 ); /*显示空闲区表*/while(1){printf("please input job's name and job's size\n");puts("input exit to exit");scanf("%s",name);if( strcmp(name,"exit")==0 ){getch( );break;}scanf("%d",&size);badest_fit( &num1,&num2,name,size );/*这里可以改为最佳适应和最先适应*/ }puts("the empty table after assigning");display_empty_table( num1 );puts("the busy table:");display_busy_table( num2 );}void initialize( ){int i;for( i=0;i<MAX;i++ ){empty[i].address=0;empty[i].length=0;empty[i].flag=0;busy[i].address=0;busy[i].length=0;strcpy(busy[i].name,"");}}int read_data( ){FILE *fp;int n=0;fp=fopen("A.txt","rb");if( fp==NULL ){puts("can't open A.txt");getch( );exit(1);}while( !feof(fp) ){fscanf(fp,"%d,%d",&empty[n].address,&empty[n].length);if( feof(fp) )break;n++;}fclose(fp);return n;}void display_empty_table( int num ){int i;printf("address\tlength\tflag\n");for( i=0;i<num;i++ )printf("%d\t%d\t%d\n",empty[i].address,empty[i].length,empty[i].flag); printf("\n");}void display_busy_table( int num ){int i;printf("address\tlength\tname\n");for( i=0;i<num;i++ )printf("%d\t%d\t%s\n",busy[i].address,busy[i].length,busy[i].name); printf("\n");}void badest_fit( int *n1,int *n2,char *name,int s ){int i,temp;temp=0;for( i=0;i<*n1;i++ ) /*寻找最大的空闲区*/if( empty[i].length>empty[temp].length)temp=i;if( s>empty[temp].length) /*申请的空间比最大的空闲区还大*/{printf("the size of memory is not enough\n");return;}busy[*n2].address=empty[temp].address;/*修改分配区表*/busy[*n2].length=s;strcpy( busy[*n2].name,name );(*n2)++;if( s==empty[temp].length ) /*若申请的空间与空闲区恰好相等*/ {for( i=temp+1;i<*n1;i++ )empty[i-1]=empty[i];(*n1)--;}else{empty[temp].address+=s;empty[temp].length-=s;}}/*最先适应算法*/void first_fit( int *n1,int *n2,char *name,int s ){int i,temp;temp=0;for( i=0;i<*n1;i++ ) /*寻找第一块空闲区*/if( empty[i].length>=s ){temp=i;break;}if( i>=*n1){printf("the size of memory is not enough\n");return;}busy[*n2].address=empty[temp].address;busy[*n2].length=s;strcpy( busy[*n2].name,name );(*n2)++;if( s==empty[temp].length ){for( i=temp+1;i<*n1;i++ )empty[i-1]=empty[i];(*n1)--;}else{empty[temp].address+=s;empty[temp].length-=s;}}/*最佳适应算法*/void best_fit( int *n1,int *n2,char *name,int s ){int i,temp;temp=0;for( i=0;i<*n1;i++ ) /*寻找最佳的空闲区*/if( empty[i].length>=s ){temp=i;break;}if( i>=*n1){printf("the size of memory is not enough\n");return;}for(i=temp+1;i<*n1;i++ ){if(empty[i].length>s&&empty[i].length<empty[i].length ) {temp=i;}}busy[*n2].address=empty[temp].address;busy[*n2].length=s;strcpy( busy[*n2].name,name );(*n2)++;if( s==empty[temp].length ){for( i=temp+1;i<*n1;i++ )empty[i-1]=empty[i];(*n1)--;}else{empty[temp].address+=s;empty[temp].length-=s; }}测试文件0,200200, 600800, 8001700, 1001800, 500。

相关文档
最新文档