可变分区存储管理方式的内存分配和回收
- 格式:doc
- 大小:19.50 KB
- 文档页数:4
课程设计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)深入了解可变分区存储管理方式的内存分配回收的实现。
二.实验内容编写程序完成可变分区存储管理方式的内存分配回收,要求有内存空间分配表,并采用最优适应算法完成内存的分配与回收。
三.实验原理在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。
为了方便主存空间的分配和去配,用于管理的数据结构可由两张表组成:“已分配区表”和“未分配区表”。
在“未分配表中”将空闲区按长度递增顺序排列,当装入新作业时,从未分配区表中挑选一个能满足用户进程要求的最小分区进行分配。
这时从已分配表中找出一个空栏目登记新作业的起始地址和占用长度,同时修改未分配区表中空闲区的长度和起始地址。
当作业撤离时已分配区表中的相应状态变为“空”,而将收回的分区登记到未分配区表中,若有相邻空闲区再将其连接后登记。
可变分区的回收算法较为复杂,当一个作业撤离时,可分为4种情况:其临近都有作业(A和B),其一边有作业(A或B),其两边均为空闲区。
尤其重要的是,在程序中利用“new类型T(初值列表)”申请分配用于存放T类型数据的内存空间,利用“delete指针名”释放指针所指向的内存空间。
四.实验部分源程序#include <iostream>using namespace std;typedef struct SNode { // Space Nodeint start,end; // 起始,结束int length; // 长度大小struct SNode *next; // 指向下一结点的指针}* SP;SP Head=(SP)malloc(sizeof(SNode)); // 全局变量,内存空间头结void DispSpace() { // 显示内存空间分配情况SP p=Head->next;cout<<"\n 空闲区说明表\n"<<"---地址--长度---\n";while (p){cout<<" "<<p->start<<" "<<p->length<<endl;p=p->next;}cout<<"----------------\n";}void Initial() { // 初始化说明表SP p,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();}void Allocation(int len) { // 分配内存给新作业SP p=Head->next,q;while (p){if (p->length < len)p=p->next;else if (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;}void CallBack(int sta,int len) { // 回收内存SP p=Head,q=p->next,r; // 开始地址和长度p->end=0;int en=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;}}else if ((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;}else if ((p->end < sta) && (q->start == en)) { // 邻区相接q->start=sta;q->length=q->end-sta;return;}else if ((p->end == sta) && (q->start < en)) { // 下邻区p->end=en;p->length=en-p->start;return;}else if (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;}}}void main() {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");}五.实验结果与体会我的体会:下面红色部分是赠送的总结计划,不需要的可以下载后编辑删除!2014年工作总结及2015年工作计划(精选)XX年,我工区安全生产工作始终坚持“安全第一,预防为主,综合治理”的方针,以落实安全生产责任制为核心,积极开展安全生产大检查、事故隐患整改、安全生产宣传教育以及安全生产专项整治等活动,一年来,在工区全员的共同努力下,工区安全生产局面良好,总体安全生产形势持续稳定并更加牢固可靠。
实验三可变分区存储管理方式的内存分配回收#include "iostream.h"#include "stdio.h"#include "stdlib.h"#include "conio.h"#define n 10//假定系统允许的最大作业数量为n#define m 10//假定系统允许的空闲区表最大为m#define minisize 100struct {float address;//已分分区起始地址float length;//已分分区长度,单位为字节int flag;//已分分区表登记栏标志,用"0"表示空栏目,实验中只支持一个字符的作业名}used_table[n];//已分分区表struct {float address;//空闲区起始地址float length;//空闲区长度,单位为字节int flag;//空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配}free_table[m];//空闲区表int allocate(char J,float xk)//采用最有分配法分配xk大小的空间//char J;//float xk;{int i,k;float ad;k=-1;for(i=0;i<m;i++)//寻找空间大于xk的最小空闲区登记项kif(free_table[i].length>=xk&&free_table[i].flag==1)if(k==-1||free_table[i].length<free_table[k].length)k=i;if(k==-1)//未找到可用空闲区,返回{cout<<"无可用空闲区"<<endl;return 0;}//找到可用空闲区,开始分配:若空闲区大小与分配的空间差小于minisize,则空闲区全部分配://若空闲区大小与要求分配的空间差大于minisize,则从空闲区划出一部分分配if(free_table[k].length-xk<=minisize){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;ad=free_table[k].address+free_table[k].length;}//修改分配区表i=0;while(used_table[i].flag!=0&&i<n)//寻找空表目{i++;if(i>=n){cout<<"无表目填写已分分区,错误"<<endl;//xx空闲区表if(free_table[k].flag==0)//前面找到的是整个空闲区free_table[k].flag=1;else //前面找到的是某个空闲区的一部分free_table[k].length=free_table[k].length+xk;return 0;}else {used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;}return 1;}//内存分配函数结束}int reclaim(char J)//回收作业名为J的作业所占内存空间//char J;{int i,k,j,s,t;float S,L;//寻找已分分区表中对应登记项s=0;while((used_table[s].flag!=J||used_table[s].flag==0)&&s<n)s++;if(s>=n)//在已分分区表中找不到名字为J的作业{cout<<"找不到该作业"<<endl;return 0;}//修改已分分区表used_table[s].flag=0;//取得归还分区的起始地址S和xxLS=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;//寻找回收分区的上下邻空闲区,上邻表目k,下邻表目jwhile(i<m&&(j==-1||k==-1)){if(free_table[i].flag==0){if(free_table[i].address+free_table[i].length==S)k=i;//找到上邻if(free_table[i].address==S+L)j=i;//找到下邻}i++;}if(k!=-1)if(j!=-1)//上邻空闲区,下邻空闲区,三项合并{free_table[k].length=free_table[j].length+free_table[k].length+L;free_table[j].flag=0;}else //上邻空闲区,下邻非空闲区,与上邻合并free_table[k].length=free_table[k].length+L;elseif(j!=-1)//上邻非空闲区,下邻为空闲区,与下邻合并{free_table[j].address=S;free_table[j].length=free_table[j].length+L;}else //上下邻均为非空闲区,回收区域直接填入{//在空闲区表中寻找空栏目t=0;while(free_table[t].flag==1&&t<m)t++;if(t>=m)//空闲区表满,回收空间失败,将已分分区表复原{cout<<"内存空闲表没有空间,回收空间失败"<<endl;used_table[s].flag=J;return 0;}free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;}return 1;}//内存归还函数结束void main(){int i,a;float xk;char J;//空闲区表初始化free_table[0].address=10240;free_table[0].length=102400;free_table[0].flag=1;for(i=1;i<m;i++)free_table[i].flag=0;//已分分区表初始化for(i=0;i<n;i++)used_table[i].flag=0;while(1){cout<<"选择功能项(0-推出,1-分配内存,2-回收内存,3-显示内存)"<<endl;cout<<"选择功项(0~3):";cin>>a;switch(a){case 0: exit(0);//a=0程序结束case 1://a=1分配内存空间cout<<"输入作业名J和作业所需长度xk:";cin>>J>>xk;allocate(J,xk);//分配内存空间break;case 2://a=2回收内存空间cout<<"输入要回收分区的作业名";cin>>J;reclaim(J);//回收内存空间case 3://a=3显示内存情况,输出空闲区表和已分分区表}cout<<"输出空闲区表:"<<endl;cout<<"起始地址分区长度标志"<<endl;for(i=0;i<m;i++)cout<<free_table[i].address<<free_table[i].length<<free_table[i].flag<<endl;cout <<"按任意键,输出已分分区表"<<endl;getch();cout<<"输出已分分区表:"<<endl;cout<<"起始地址分区长度标志"<<endl;for(i=0;i<n;i++)if(used_table[i].flag!=0)cout<<used_table[i].address<<used_table[i].length<<used_table[i].flag<<endl;elsecout<<used_table[i].address<<used_table[i].length<<used_table[i].flag<<endl; break;default:cout<<"没有该选项"<<endl;}}执行结果:选择0:选择1:。
计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收内存管理是操作系统中非常重要的一个功能,它负责管理计算机内存资源的分配和回收。
内存分配是指在程序运行时,为进程分配适当大小的内存空间;内存回收是指当进程终止或不再需要分配的内存时,将它们释放回系统。
可变分区存储管理方式是一种常用的内存管理方式,它的特点是将内存分为若干个可变大小的分区。
下面将详细介绍可变分区存储管理方式的内存分配和回收。
一、内存分配:1. 首次适应算法(First Fit):从起始地址开始查找第一个满足分配要求的可用分区,分配其中一部分给进程,并将剩余部分作为新的可用分区。
2. 循环首次适应算法(Next Fit):与首次适应算法类似,但是从上一次分配的位置开始查找。
3. 最佳适应算法(Best Fit):在所有可用分区中找到最小且能满足分配要求的分区进行分配。
4. 最坏适应算法(Worst Fit):在所有可用分区中找到最大的空闲分区进行分配。
这种方法可能会造成大量外部碎片,但可以更好地支持大型进程。
二、内存回收:1.碎片整理:在每次回收内存时,可以通过将相邻的空闲分区合并为一个更大的分区来减少外部碎片。
这种方法需要考虑如何高效地查找相邻分区和合并它们。
2.分区分割:当一个进程释放内存时,生成的空闲分区可以进一步划分为更小的分区,并将其中一部分分配给新进程。
这样可以更好地利用内存空间,但会增加内存分配时的开销。
3.最佳合并:在每次回收内存时,可以选择将相邻的空闲分区按照最佳方式合并,以减少外部碎片。
4.分区回收:当一个进程终止时,可以将其所占用的分区标记为可用,以便其他进程使用。
三、优化技术:1.预分配内存池:为了避免频繁的内存分配和回收,可以预分配一定数量的内存作为内存池,由进程从内存池中直接分配和回收内存。
2.内存压缩:当内存不足时,可以通过将一部分进程的内存内容移动到磁盘等外部存储器中,释放出一定的内存空间。
3.页面替换算法:在虚拟内存系统中,当物理内存不足时使用页面替换算法,将不常用的页面淘汰出物理内存,以便为新页面分配内存。
主存空间的分配和回收采用可变分区管理1、采用可变分区管理,使用首次获最佳适应算法实现主存的分配和回收要求采用分区说明表进行。
提示:(1)可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量,查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若无,则作业等待。
随着作业的装入、完成,主存空间被分割成许多大大小小的分区。
有的分区被作业占用,有的分区空闲。
例如,某时刻主存空间占用情况如图3-1所示。
为了说明哪些分区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,如图3-2所示。
图3-1 内存空闲分区图图3-2 空闲区说明表其中,起始地址指出各空闲区的主存起始地址,长度指出空闲区的大小。
状态:未分配----该栏目记录的是有效的空闲区;空表目----没有登记信息。
由于分区数目不定,所以空闲区说明表中应有足够的空表目项。
否则造成溢出,无法登记。
同样,再设一个已分配区表,记录作业或进程的主存占用情况。
(2)当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。
有时找到的空闲区可能大于作业需求量,这时应将空闲区一分为二。
一个分给作业;另一个仍作为空闲区留在空闲区表中。
为了尽量减少由于分割造成的碎片,尽可能分配低地址部分的空闲区,将较大空闲区留在高地址端,以利于大作业的装入。
为此在空闲区表中,按空闲区首地址从低到高进行登记。
为了便于快速查找,要不断地对表格进行紧缩,即让“空表目”项留在表的后部。
(3)当一个作业执行完成时,作业所占用的分区应归还给系统。
在归还时要考虑相邻空闲区合并的问题。
作业的释放区与空闲区的邻接分以下四种情况考虑:① 释放区下邻(低地址邻接)空闲区;② 释放区上邻(高地址邻接)空闲区③ 释放区上下都与空闲区邻接;④ 释放区与空闲区不邻接。
(4)请按首次(或最佳)适应分配算法设计主存分配和回收程序。
哈尔滨理工大学课程设计(操作系统)题目:可变分区分配与回收—采用最坏算法班级:计算机科学与技术学院计算机系10-8班姓名:张兢 1004010813指导教师:高雪瑶系主任:林克正2013年03月01日一、课程设计目的1、背景主存是CPU可直接访问的信息空间,合理而有效的使用贮存将在很大程度上影响整个计算机系统的性能。
本课题要求模拟实现分区式主存管理机制。
模拟实现各种分区管理方法以及相应的主存分配以及回收算法。
2、目的通过该课题进一步加深对可变分区存储机制的理解。
加深对存储器动态分区分配算法的认识。
掌握“首次适应算法”、“下次适应算法”、“最佳适应算法发”、“最坏适应算法”的内存分配过程。
掌握内存的回收策略。
二、课题任务描述1、设计可用的内存空闲空间,并能动态输入用户作业所需的内存大小。
2、编程模拟各种分配算法的实施过程,允许自行选择如“首次适应算法”、“下次适应算法”、“最佳适应算法发”、“最坏适应算法”等常用算法,要求实现不少于三种算法。
3、实现内存的回收。
要求考虑回收时的内存合并问题。
三、课题研发相关知识(包含所用库函数的介绍)1、首次适应算法(first fit)FF算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始顺序查找,直至找到一个大小能男足要求的空闲分区位置;然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍留在空闲链中。
若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。
但是,低址部分不断被划分,会留下许多难以利用的很小的空闲分区。
2、最佳适应算法(best fit)所谓“最佳”是指每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。
为了加速寻找,该算法要求将所有的空闲分区按其容量以从小到大的顺序形成一空闲分区链。
这样,第一次找到的能满足要求的空闲区,必然是最佳的。
这样,在存储器中会留下许多难以利用的小空闲区。
可变分区存储管理方案中的内存分配/*(二)可变分区存储管理方案中的内存分配可变分区调度算法有:最先适应分配算法,最优适应分配算法,最坏适应算法用户提出内存空间的申请;系统根据申请者的要求,按照一定的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者;当程序执行完毕或主动归还内存资源时,系统要收回它所占用的内存空间或它归还的部分内存空间。
1.程序运行时首先接收输入:空闲区数据文件,包括若干行,每行有两个数据项:起始地址、长度(均为整数),各数据项以space隔开。
2.建立空闲区表并在屏幕上显示输出空闲区表内容,空闲区表中记录了内存中可供分配的空闲区的始址和长度,用标志位指出该分区是否是未分配的空闲区。
3.从用户界面根据用户提示接收一个内存申请,格式为:作业名、申请空间的大小。
4.按照最差(最坏)适配算法选择一个空闲区,分割并分配,修改相应的数据结构(空闲区表),填写内存已分配区表(起始地址、长度、标志位),其中标志位的一个作用是指出该区域分配给哪个作业。
5.重复3、4,直到输入为特殊字符(0)。
6.在屏幕上显示输出新的空闲区表和已分配区表的内容。
本程序包括:FIFO,最优适应分配算法,最坏适应算法input file:freememory.txtdata:10 1530 550 2080 12120 25160 18200 8VC++调试通过*/#include#include#include#includeconst 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++)< p="">{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;< p="">cin>>fname;if ((fp=fopen(fname,"r"))==NULL){cout<<"错误,文件打不开,请检查文件名"<<endl;< p="">}else{while(!feof(fp)){fscanf(fp,"%d %d",&frees[free_quantiry].start,&frees[free_qu antiry].length);free_quantiry++;}return 1;}return 0;}//sortvoid sort()//按空闲区起始地址排序{int i,j,p;for (i=0;i<free_quantiry;i++)< p="">{p=i;for (j=i+1;j<free_quantiry;j++)< p="">{if (frees[j].start<frees[p].start)< p="">{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;< p="">cout<<"当前空闲表:"<<endl;< p="">cout<<"起始地址长度状态"<<endl;< p="">for(i=0;i<free_quantiry;i++)< p="">{cout.setf(2);cout.width(12);cout<<frees[i].start;< p="">cout.width(10);cout<<frees[i].length;< p="">cout.width(8);cout<<frees[i].tag<<endl;< p="">}cout<<endl<<"-----------------------------------------------"<<endl;< p="">cout<<"当前已分配表:"<<endl;< p="">cout<<"起始地址长度占用作业名"<<endl;< p="">for (i=0;i<occupy_quanity;i++)< p="">{cout.setf(2);cout.width(12);cout<<occupys[i].start;< p="">cout.width(10);cout<<occupys[i].length;< p="">cout.width(8);cout<<occupys[i].tag<<endl;< p="">}}//最优适应分配算法void best_fit(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:"<<endl;< p="">cin>>job_name;cin>>job_length;flag=0;for (i=0;i<free_quantiry;i++)< p="">{if (frees[i].length>=job_length){flag=1;}}if (flag==0){cout<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<="">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++)< p="">if((frees[j].length>=job_length)&&frees[j].length<frees[i].length) < p="">{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++)< p="">{frees[j]=frees[j+1];}free_quantiry--;cout<<"内存分配成功"<<endl;< p="">}}}//撤销作业void finished()char job_name[20];int i,j,flag,p=0;int start;int length;cout<<"请输入要撤销的作业名:"<<endl;< p="">cin>>job_name;flag=-1;for (i=0;i<occupy_quanity;i++)< p="">{if (!strcmp(occupys[i].tag,job_name)){flag=i;start=occupys[i].start;length=occupys[i].length;}}if (flag==-1){cout<<"没有这个作业"<<endl;< p="">}else{for (i=0;i<free_quantiry;i++)< p="">{if ((frees[i].start+frees[i].length)==start){if(((i+1)<free_quantiry)&&(frees[i+1].start==start+length))< p=""> {frees[i].length=frees[i].length+frees[i+1].length; for (j=i+1;j<free_quantiry;j++)< p="">{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++)< p="">{occupys[i]=occupys[i+1];}occupy_quanity--;}}//显示版权信息函数void version(){cout<<endl<<endl;< p="">cout<<" ┏━━━━━━━━━━━━━━━━━━━━━━━┓"<<endl;< p="">cout<<" ┃可变分区存储管理方案中的内存分配┃"<<endl;< p="">cout<<" ┠───────────────────────┨"<<endl;< p="">cout<<" ┃siqingyang ┃"<<endl;< p="">cout<<" ┃version 2011 build 0520┃"<<endl;< p="">cout<<" ┗━━━━━━━━━━━━━━━━━━━━━━━┛"<<endl;< p="">cout<<endl<<endl;< p="">}void main(){int flag=0;int t=1;int chioce=0;version();initial();flag=readData();view();while(flag==1){sort();cout<<endl<<endl<<"===================================================="<<endl;</p><p>cout<<" p="" 可变分区存储管理模拟系统"<<endl;<="">cout<<"================================= ========================"<<="" p="">cout<<" 1.best fit申请空间2.撤消作业0.退出"<<endl;< p=""> cout<<"请选择:";cin>>chioce;switch(chioce){case 1:best_fit();view();break;case 2:finished();view();break;case 0:flag=0;break;default:cout<<"选择错误!"<<endl;< p="">}}}</endl;<></endl;<></endl<<endl<<"========================== ========================></endl<<endl;<></endl;<></endl;<></endl;<></endl;<></endl;<></endl;<></endl<<endl;<></occupy_quanity;i++)<></free_quantiry;j++)<></free_quantiry)&&(frees[i+1].start==start+length))<> </free_quantiry;i++)<></endl;<></occupy_quanity;i++)<></endl;<></endl;<></free_quantiry-1;j++)<></frees[i].length)<></free_quantiry;j++)<></free_quantiry;i++)<></endl;<></occupys[i].tag<<endl;<></occupys[i].length;<></occupys[i].start;<></occupy_quanity;i++)<></endl;<></endl;<></endl<<"-----------------------------------------------"<<endl;<></frees[i].tag<<endl;<></frees[i].length;<></frees[i].start;<></free_quantiry;i++)<></endl;<></endl;<></endl<<"----------------------------------------------------------"<<endl;<></frees[p].start)<></free_quantiry;j++)<></free_quantiry;i++)<></endl;<></endl;<></maxjob;i++)<>。
可变分区存储管理方式的内存分配和回收第一篇:可变分区存储管理方式的内存分配和回收#include//定义输入/输出函数#include//数据流输入/输出#include//字符串处理#include//参数化输入/输出const int MJ=10;//假定系统允许的最大作业数量为10typedef 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<cin>>fn;if((fp=fopen(fn,“r”))==NULL){ 其意义是在当前目录下打开文件file a,只允许进行“读”操作,并使fp指向该文件cout<}else{while(!feof(fp)){fscanf(fp,“%d,%d”,&frees[free_quantity].address,&frees[free_quantity].length);free_quantity++;fscanf(文件指针,格式字符串,输入表列);}return 1;}return 0;}void sort(){int i,j,p;for(i=0;ip=i;for(j=i+1;jif(frees[j].addressp=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}void view(){int i;cout<cout<for(i=0;icout.setf(2); cout.width(12); cout<cout.width(10); cout<cout.width(8); cout<}cout<cout<for(i=0;icout.setf(2); cout.width(12); cout<cout.width(10); cout<cout.width(8); cout<}}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;iif(frees[i].length>=job_length){flag=1;}}if(flag==0){//未找到空闲区,返回cout<}else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){//找到可用空闲区,开始分配t=1;}i++;}i--;occupys[occupy_quantity].address=frees[i].address;//修改已分配区表strcpy(occupys[occupy_quantity].tag,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;jfrees[j]=frees[j+1];}free_quantity--;cout<}}}void reclaim()//回收作业所占的内存空间{char job_name[20];int i,j,flag,p=0;int address;int length;//寻找已分分区表中对应的登记项cout<cin>>job_name;flag=-1;for(i=0;iif(!strcmp(occupys[i].tag,job_name)){flag=i;address=occupys[i].address;length=occupys[i].length;}}if(flag==-1){ //在已分分区表中找不到作业cout<}else{//修改空闲区表,加入空闲表for(i=0;iif((frees[i].address+frees[i].length)==address){ if(((i+1)for(j=i+1;jfrees[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++;}//删除分配表中的该作业for(i=flag;ioccupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int flag=0;int t=1;int chioce=0;int i;for(i=0;ifrees[i].address=-1;//空闲区表初始化frees[i].length=0;strcpy(frees[i].tag,“free”);occupys[i].address=-1;//已分分区表初始化occupys[i].length=0;strcpy(occupys[i].tag,“");}free_quantity=0;occupy_quantity=0;flag=read();while(flag==1){sort();cout<cin>>chioce;switch(chioce){case 0:flag=0;break;case 1:ear();break;case 2:reclaim();break;case 3:view();break;default:cout<}}}第二篇:可变分区存储管理方式的内存分配和回收实验报告一.实验目的通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。
0 10k主存空间的分配和回收一、实验目的设计一个可变式分区分配的存储管理方案。
并模拟实现分区的分配和回收过程。
对分区的管理法可以是下面三种算法之一: 首次适应算法 循环首次适应算法 最佳适应算法二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。
所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。
可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、循环首次适应算法、最佳适应算法三种算法来实现主存的分配与回收。
同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。
三、实验主要仪器设备和材料实验环境:硬件环境:IBM-PC 或兼容机 软件环境:Visual C++6.0四、实验原理及设计方案采用可变分区管理,使用首次或最佳适应算法实现主存的分配和回收1、可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
为了说明那些分区是空闲的,可以用来装入新作业,必须有一张空闲说明表 例如:空闲区说明表格式如下:第二栏其中,起址——指出一个空闲区的主存起始地址,长度指出空闲区的大小。
内存可变分区分配算法的分配和回收下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!引言内存管理是计算机系统中至关重要的一部分,而可变分区分配算法是其中的一种常见方法。
可变分区存储管理方式的内存分配和回收实验报告【实验报告】一、实验目的了解可变分区存储管理方式的内存分配和回收过程,了解最优算法的原理和实现方法,掌握最优算法在可变分区存储管理方式下的内存分配和回收操作。
二、实验原理最优算法的分配过程如下: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.碎片整理在连续进行分配和释放操作后,内存空闲分区链可能产生内部碎片和外部碎片。
内部碎片是指分配给进程的内存空间超过其所需的大小,而外部碎片是指分配给进程之间的多个空闲分区无法满足一些较大分区的请求。
为了减少碎片的数量和大小,操作系统可以进行碎片整理操作,将零散的空闲分区重新组合为一个或多个更大的分区,以提供更大的连续内存空间。
总的来说,可变分区存储管理方案通过灵活地将内存空间划分为可变大小的分区,并采用不同的分配策略进行内存分配,以满足各个进程的内存需求。
同时,通过回收和合并空闲分区及进行碎片整理,可以最大程度地提高内存资源的利用率。
然而,可变分区存储管理方案需要维护和更新空闲分区链,同时可能会产生内部碎片和外部碎片,因此在设计和实现时需要综合考虑各种因素,以提高内存管理的效率和性能。
计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收概述内存管理是操作系统中重要的一部分,它负责管理计算机内存的分配和回收。
可变分区存储管理方式是一种常用的内存管理方案,它将内存分为多个不同大小的分区,每个分区可以被分配给一个进程来使用。
本文将介绍可变分区存储管理方式的内存分配和回收过程。
内存分配可变分区存储管理方式的内存分配过程包括空闲分区的选择和分区的划分。
空闲分区的选择在可变分区存储管理方式中,操作系统需要选择一个合适的空闲分区来分配给进程。
常用的空闲分区选择算法有:•首次适应算法(First Fit):从头开始寻找满足进程需要的空闲分区。
•最佳适应算法(Best Fit):从所有满足进程需要的空闲分区中选择大小最接近的一个。
•最差适应算法(Worst Fit):选择能够满足进程需要且最大的空闲分区。
选择合适的空闲分区算法可以提高内存利用率和分配的效率。
分区的划分一旦选择了合适的空闲分区,操作系统需要对该分区进行划分,以满足进程的内存需求。
常用的分区划分方式包括:•等分划分:将空闲分区按照进程的内存需求进行等分划分。
•保留部分划分:只将进程需要的内存大小分配给进程,剩余的空闲分区保留。
分区的划分方式可以根据实际情况选择,以满足不同进程的内存需求。
内存回收可变分区存储管理方式的内存回收过程包括释放分区和合并分区两个步骤。
释放分区当一个进程终止或释放了分配给它的内存分区时,该分区将被标记为空闲,可以被其他进程使用。
合并分区在进行内存回收时,为了提高内存利用率,操作系统通常会进行分区的合并。
合并分区需要考虑到合并后的分区是否满足其他进程的内存需求。
常用的合并分区策略有:•相邻空闲分区合并:将相邻的两个空闲分区合并成一个更大的空闲分区。
•首次适应合并:从头开始寻找空闲分区,如果找到两个相邻的空闲分区,可以将它们合并起来。
通过合并分区,可以减少内存碎片,提高内存的利用率。
可变分区存储管理方式是一种常用的内存管理方案,在内存分配和回收过程中,通过选择合适的空闲分区和分区的划分以及合并分区,可以高效地管理计算机内存,提高内存利用率。
操作系统实验报告可变分区存储管理方式的内存分配回收可变分区存储管理方式是一种常见的内存分配和回收策略,通过将内存分成若干大小不等的分区,分配给不同大小的进程使用。
本文将对可变分区存储管理方式的内存分配和回收进行详细介绍。
首先,可变分区存储管理方式需要对内存进行划分,将内存分成若干个大小不等的分区。
这些分区可以是固定大小的,也可以是可变大小的。
当进程申请内存时,系统会根据申请内存的大小来选择一个合适大小的分区进行分配。
分配时分为两种情况:首次适应和最佳适应。
首次适应算法是指从内存的起始位置开始遍历分区,找到第一个能满足进程要求的分区进行分配。
这种算法的优点是找到满足条件的分区速度较快,缺点是容易造成较大的内存碎片。
最佳适应算法是指通过遍历整个内存,找到一个大小最接近进程要求的分区进行分配。
这种算法的优点是能够减小内存碎片的产生,但是分配速度较慢。
当进程结束时,需要回收其占用的内存。
对于可变分区存储管理方式,在回收内存时出现了两种情况:内部碎片和外部碎片。
内部碎片是指分配给进程的分区中,有一部分空闲内存无法被其他进程利用。
这是因为当一些进程需要分配内存时,分配的大小可能大于其实际需要的大小,导致分区中留下了空余空间。
解决内部碎片的方法是动态地调整分区的大小,使其能够更好地适应进程的大小需求。
外部碎片是指存储空闲的分区之间的一些不可利用的内存。
当进程需要分配内存时,可能没有一个分区能满足其大小需求,导致无法分配内存。
解决外部碎片的方法是内存紧缩和分区合并。
内存紧缩是指将内存中的进程向一端移动,使剩余的空闲内存空间连在一起。
这样可以使得所有的空闲内存空间都可以被利用,减少外部碎片的产生。
分区合并是指将不连续的空闲分区进行合并,形成更大的连续空闲分区。
这样可以提供给大型进程使用,减少外部碎片的产生。
综上所述,可变分区存储管理方式的内存分配和回收是一个动态的过程,需要根据进程的需求进行灵活地管理。
它可以通过首次适应或最佳适应算法选择合适的分区进行内存分配,通过动态调整分区大小解决内部碎片问题,并通过内存紧缩和分区合并减少外部碎片的产生。
#include<iostream>#include<stdlib.h>#define MAX_SIZE 10000#define BUSY 1#define FREE 0#define LIMIT_SIZE 100using namespace std;struct MemoryBlock{MemoryBlock *front,*next;long size;long addr;int PID;int state;}*head,*cur,*tmp;int PIDcnt;void init(){PIDcnt=0;head=new MemoryBlock;head->next=NULL;head->size=MAX_SIZE;head->addr=0;head->state=0;}void Redis(){cur=head;while(cur){if(cur->state==1){cur=cur->next;continue;}if(cur->next==NULL) break;MemoryBlock *n=cur;cur=cur->next;while(cur->state==1){cur=cur->next;} MemoryBlock *f=n;while(n!=cur){n=n->next;n->addr-=f->size;}cur->size+=f->size;if(f==head){head=f->next;}else{f->front->next=f->next;f->next->front=f->front;}delete f;}// Show();}void Show(){cur=head;int num=0;puts("---------------------------------------------------\n");cout<<"num "<<"addr "<<"size "<<"state "<<"PID "<<endl;while(cur!=NULL){printf("%-6d%-8d%-8d%-8d",++num,cur->addr,cur->size,cur->state);if(cur->state)cout<<cur->PID;cout<<endl;cur=cur->next;}puts("\n---------------------------------------------------\n");}void Alloc(){int flag=1;int u_size;cur=head;cout<<"please input the size:"<<endl;cin>>u_size;while((cur!=NULL)&&flag==1){if(cur->size<u_size||cur->state==1)cur=cur->next;else {if((cur->size-u_size)<LIMIT_SIZE){cur->state=1;cur->PID=++PIDcnt;flag=cur->addr;}else {MemoryBlock *tMB=new MemoryBlock;if(cur==head){head=tMB;}else{cur->front->next=tMB;tMB->front=cur->front;}cur->front=tMB;tMB->next=cur;tMB->addr=cur->addr;tMB->size=u_size;tMB->state=1;tMB->PID=++PIDcnt;cur->addr+=u_size;cur->size-=u_size;flag=tMB->addr;}}}if(flag==1){Redis();cur=head;while((cur!=NULL)&&flag==1){if(cur->size<u_size||cur->state==1)cur=cur->next;else {if((cur->size-u_size)<LIMIT_SIZE){cur->state=1;cur->PID=++PIDcnt;flag=cur->addr;}else {MemoryBlock *tMB=new MemoryBlock;if(cur==head){head=tMB;}else{cur->front->next=tMB;tMB->front=cur->front;}cur->front=tMB;tMB->next=cur;tMB->addr=cur->addr;tMB->size=u_size;tMB->state=1;tMB->PID=++PIDcnt;cur->addr+=u_size;cur->size-=u_size;flag=tMB->addr;}}}if(flag==1){puts("---------------------------------------\n");cout<<"failed,without enough memory!\n"<<endl;puts("---------------------------------------\n");}else {puts("---------------------------------------\n");cout<<"succeed,the memory block begin from "<<flag<<endl<<endl;puts("---------------------------------------\n");}}else {puts("---------------------------------------\n");cout<<"succeed,the memory block begin from "<<flag<<endl<<endl;puts("---------------------------------------\n");}}void Recycle(){int ID;int flag=1;cur=head;cout<<"please input the PID of the process you want to delete:";cin>>ID;while(flag&&cur){if(cur->state==1&&cur->PID==ID){if(cur!=head){if(cur->front->state==0){cur->front->size+=cur->size;cur->front->next=cur->next;cur->next->front=cur->front;tmp=cur;cur=cur->front;delete tmp;}}if(cur->next!=NULL){if(cur->next->state==0){cur->size+=cur->next->size;if(cur->next->next!=NULL)cur->next->next->front=cur;tmp=cur->next;cur->next=cur->next->next;delete tmp;}}cur->state=0;flag=0; }cur=cur->next;}if(flag==1){puts("---------------------------------------\n");cout<<"failed,without such process!\n"<<endl;puts("---------------------------------------\n");}else {puts("---------------------------------------\n");cout<<"succeed,process "<<ID<<" has been deleted"<<endl<<endl;puts("---------------------------------------\n");}}int main(){int i;char c;init();puts("___________welcome to Operating systen curriculum project___________\n");while(1){puts("1.Allocate memory\n");puts("2.Recycle memory\n");puts("3.Redistribut memory\n");puts("4.show the memory state\n");puts("0.exit\n");c=getchar();switch(c){case '1': Alloc();getchar();break;case '2':Recycle();getchar();break;case '3': Redis();getchar();break;case '4':Show();getchar();break;case '0':return 0;default:getchar();}}}。
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;
}
}
}。