动态可变分区存储管理模拟系统解析

青岛农业大学理学与信息科学学院操作系统课程设计报告设计题目仿真实现动态可变分区存储管理模拟系统—最佳适应算法和最先适应算法学生专业班级计算机科学与技术2011级03班学生姓名(学号)张明珠(H20110684 )设计小组其他同学姓名(学号)刘玉婷(H20110661)宋璇(H20110162)指导教师牟春莲完成时间 2014. 06.15 实习(设计)地点信息楼2182014年6月16日一、课程设计目的操作系统的理论知识只有通过操作系统的实际操作和编程才能真正地理解和掌握,没有实践操作系统的操作和编程,学习操作系统就是纸上谈兵。

操作系统课程设计是在学习完《操作系统》课程后进行的一次全面、综合实习,是计算机科学与技术专业的重要实践性教学环节。

通过课程设计,达到如下目的:1、巩固和加深对操作系统原理的理解,提高综合运用本课程所学知识的能力。

2、培养学生选用参考书,查阅手册及文献资料的能力;培养独立思考、深入研究、分析问题、解决问题的能力。

3、通过实际操作系统的分析设计、编程调试,掌握系统软件的分析方法和工程设计方法。

4、能够按要求编写课程设计报告书,能正确阐述设计过程和实验结果、正确绘制系统和程序框图。

5、通过课程设计,培养学生严谨的科学态度、严肃认真的工作作风和团队协作精神。

二、设计任务题目描述:仿真实现动态可变分区存储管理模拟系统。

内存调度策略可采用最先适应算法、最佳适应法等,并对各种算法进行性能比较。

为了实现分区分配,系统中必须配置相应的数据结构,用来描述空闲区和已分配区的情况,为分配提供依据。

常用的数据结构有两种形式:空闲分区表和空闲分区链。

为把一个新作业装入内存,须按照一定的算法,从空闲分区表或空闲分区链中选出一个分区分配给该作业.设计要求:1.采用指定算法模拟动态分区管理方式的主存分配。

能够处理以下的情形:⑴随机出现的进程i申请jKB内存,程序能判断是否能分配,如果能分配,要求输出分配的首地址Faddress,并要求输出内存使用情况和空闲情况。

内存情况输出的格式为:Faddress该分区的首地址;Eaddress该分区的尾地址Len 分区长度;Process 如果使用,使用的进程号,否则为0。

⑵主存分配函数实现寻找空闲区、空闲区表的修改、已分配区表的修改功能。

成员分工:张明珠申请内存、查看进程之间的前后的区域状态、释放进程刘玉婷最先适应算法、将其释放的内存插入空闲块中、初始化宋璇最佳适应算法、将新项插入已分配表中、退出张明珠宋璇刘玉婷整个界面的优化、界面设计、总体思路三、分析与设计1.设计思路存储器是计算机的重要组成部分,存储空间是操作系统管理的宝贵资源,虽然其容量在不断扩大,但仍然远远不能满足软件发展的需要。

对存储资源进行有效的管理,不仅关系到存储器的利用率,而且还对操作系统的性能和效率有很大的影响。

操作系统的存储管理的基本功能有:存储分配、地址转换和存储保护、存储共享、存储扩充。

存储分配指为选中的多道运行的作业分配主存空间;地址转换是把逻辑地址空间中的用户程序通过静态重定位或动态重定位转换和映射到分给的物理地址空间中,以便用户程序的执行;存储保护指各道程序只能访问自己的存储区域,而不能互相干扰,以免其他程序受到有意或无意的破坏;存储共享指主存中的某些程序和数据可供不同用户进程共享。

最简单的单道系统中,一旦一个程序能装入主存,它将一直运行直到结束。

如果程序长度超出了主存的实际容量,可以通过覆盖和交换的技术获得解决。

更多的操作系统支持多个用户进程在主存同时执行,能满足多道程序设计需要的最简单的存储管理技术是分区方式,有分固定分区和可变分区。

可变分区的分配(如图(1)所示)算法包括:最先适应、下次适应、最佳适应、最坏适应和快速适应等分配算法。

图(1)动态内存分配采用分区方式管理存储器,每道程序总是要求占用主存的一个或几个连续的存储区域,主存中会产生许多碎片。

因此,有时为了接纳一个新的作业而往往要移动已在主存的信息,这不仅不方便,而且开销不小。

现代计算机都有某种虚存硬设备支持,简单也是常用的虚存是请求分页式虚存管理,于是允许把一个进程的页面存放到若干不相邻的主存页框中。

从搜索速度上看,最先适应算法具有最佳性能。

从回收过程来看,最先适应法也是最佳的。

最先适应算法要求可用表或自由链接按起始地址递增的次序排列。

该算法的最大特点是一旦找到大于或等于所要求内存的长度的分区,则搜索结束。

其优点:(1)、在释放内存分区时,如果有相邻的空白区就进行合并,使其成为一个较大的空白区;(2)、本算法的实质是尽可能的利用存储器的低地址部分,在高地址部分则保留较多的或较大的空白区,以后如果需要较大的空白区,就容易能够满足。

最佳适应算法:从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。

为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。

该算法保留大的空闲区,但造成许多小的空闲区。

最佳适应算法将可利用空间表中一个大小不小于“请求”且最接近“请求”的空闲块的一部分分配给用户。

分配与回收都需要对可利用空间表从头至尾查询一遍。

为了避免每次分配都要查询整个链表,通常要求节点从大到小排序,由此只需找到第一个足够大的空闲块即可予以分配。

但回收时,必须把回收的空闲块放置在符合大小顺序关系的链表位置。

在分配时容易产生太小而无法利用的内存碎片,同时这种做法也保留了那些很大的内存块以备响应将来发生的内存量较大的用户“请求”,从而使整个链表逐渐趋向于节点大小差别甚远的状态。

这种分配算法适合请求分配内存大小范围较广的系统,此算法比较费时间。

在进行内存分配时,从空闲分区表(或空闲分区链)首开始顺序查找,直到找到第一个能满足其大小要求的空闲分区为止。

如果该空闲分区大于作业的大小,则从该分区中划出一块内存空间分配给请求者,将剩余空闲区仍然留在空闲分区表(或空闲分区链)中。

最佳适应算法的特点:按最佳适应算法为作业分配内存,就能把既满足作业要求又与作业大小最接近的空闲分区分配给作业。

保留了大的空闲区,但分割后的剩余空闲区很小。

本课程设计就是分析动态分区法,与固定分区法相比,动态分区法在作业执行前并不建立分区,分区的建立是在作业的处理过程中进行的。

且其大小可随作业或进程对内存的要求而改变分区的建立是在作业的处理过程中进行的。

且其大小可随作业或进程对内存的要求而改变。

这就改变了固定分区法中那种即使是小作业也要占据大分区的浪费现象,从而提高了内存的利用率。

2.概要设计动态分区分配是根据进程的实际需要,动态地为之分配内存空间。

在实现可变分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配和回收操作这样三个问题。

为了实现分区分配,系统中必须配置相应的数据结构,用来描述空闲区和已分配区的情况,为分配提供依据。

常用的数据结构有两种形式:空闲分区表和空闲分区链。

为把一个新作业装入内存,须按照一定的算法,从空闲分区表或空闲分区链中选出一个分区分配给该作业。

目前常用的分配算法有:首次适应算法、循环首次适应算法、最佳适应算法、最坏适应算法和快速适应算法。

在动态分区存储管理方式中,主要操作是分配内存和回收.系统模块划分:图(3)主流程图各程序模块的调用层次:数据结构结构体定义进程struct area {int start;int end;int len;int sign;struct area * next;};5个数据成员,分别为:start(分区的首地址)、end、(分区尾地址)len(分区的长度)、sign(标志进程状态)、next(指针用来指向下一个进程)。

内存分配图(5)内存分配图最先适应算法流程如下图所示请求SIZE大小的分区:最佳适应算法流程如下图所示:图(7)最佳适应算法流程图四、系统实施在模拟过程中,没有充分理解操作系统教程上关于动态分区法、最先适应法、最优适应法的概念,造成了对设计的目的设计不清楚,不能很好地表达出此设计的功能寻找空白区方法的不同:分区分配是对可用表(或自由链)数据结构进行操作,空闲区表可以按空闲区大小的升序(降序)和空闲区首址升序(降序)两种方法进行组织。

才开始并没有理解这两种分配方式对这最佳适应算法和最先适应算法的影响,导致混淆,出现了错误。

对题目理解有误,对模块之间的关系设计不是很清晰。

图(8)初始化图图(9) 申请内存图图(10)查看已分配区图图(11)查看空闲区图图(12)释放内存图图(13)查看内存状态图最佳算法和最先算法的比较:图(13)两算法的对比图五、程序清单#include<iostream>using namespace std;#include<fstream>struct area {int start; 定义分区的首地址int end; 定义分区的尾地址int len; 定义分区的长度int sign;定义分区的进程号struct area * next;定义进程的指针};struct area*freehead=NULL;声明freehead 是型结构指针。

初始freehead指针为空。

struct area*usedhead=NULL;声明usedhead 是型结构指针。

初始usedhead指针为空。

void create();创建内存区void print(area*);void ask(area*);void ask1(area*);void correct(area*,int);area * delempty();初始化void inserused(area *,int ,int );void inserfree(area * );void setfree();void listID();//最先适应法void listlen();/最优适应法void swap(area *,area *);//初始化area * delempty(){area * p1=freehead;把空闲区首地址赋值给p1if(p1->len==0){if(p1->next==NULL)return NULL;else {p1=p1->next;指向下一个地址}}}//最优适应法void listlen(){int n=0; 初始为零area *p9=freehead->next,*p0=freehead,*p11,*p12,*p13;while(p0!=NULL){不为空p0=p0->next;指向下一个地址n++;n加一}p0=freehead;把空闲区赋值给p0if (n==1)return;elsewhile(p9!=NULL) {p12=p0; 把p0空闲区给p12p13=p9;把p9空闲区给p13p0=p0->next; p0指向下一个地址p9=p9->next;while(p13!=NULL)//把空闲区按从小到大的顺序排列{if((p12->len)>(p13->len)){如果p12长度>p13长度p11=new area;//把p13给p11p11->end=p13->end;p11->len=p13->len;p11->sign=p13->sign;p11->start=p13->start;p11->next=NULL;swap(p13,p12);交换两个P13,P12swap(p12,p11);交换两个P12,P11}p13=p13->next;}}}void swap(area *p13,area *p14){p13->len=p14->len;p13->sign=p14->sign;p13->end=p14->end;p13->start=p14->start;}//最先适应法void listID(){int n=0;area *p9=freehead->next,*p0=freehead,*p11,*p12,*p13;while(p0!=NULL){p0=p0->next;n++;}p0=freehead;if (n==1)return;elsewhile(p9!=NULL) {p12=p0;p13=p9;p0=p0->next;p9=p9->next;while(p13!=NULL)//把地址按递增顺序排列{if((p12->start)>(p13->start)){p11=new area;p11->end=p13->end;p11->len=p13->len;p11->sign=p13->sign;p11->start=p13->start;p11->next=NULL;swap(p13,p12);swap(p12,p11);}p13=p13->next;}}}void inserfree(area * p3){查看进程之间的前后的区域状态int flag=0;area *pf=freehead,*pe=freehead,*pe1;while(pf!=NULL){if(pf->end!=p3->start)//判断是否有前继空闲块pf=pf->next;else break;}if(pf!=NULL){flag=5;}//flag=5 有前置空闲块else flag=1;//没有置1while(pe!=NULL)//判断是否有后继空闲块{if(pe->start!=p3->end){pe1=pe;pe=pe->next;}else break;}if(pe!=NULL) {if(flag==5)flag=6;else flag=4;}//有前置且有后置FLAG=6,只有后置=4 else{if(flag==1)flag=2;}//前后都没有置2switch(flag){case 5:pf->end=pf->end+p3->len;前置空闲块pf->len=pf->len+p3->len;break;case 4:pe->start=pe->start-p3->len;只有后置pe->len=pe->len+p3->len;break;case 2: area* p8;p8=new area;p8->start=p3->start;p8->len=p3->len;p8->sign=0;p8->end=p3->end;p8->next=freehead;freehead=p8;break;case 6:pf->end=pe->end;有前置与后置pf->len=pf->len+pe->len+p3->len;if(pe->next==NULL){pe1->next=NULL;delete pe;}else {if(pe==freehead){freehead=pe->next;delete pe;}else {pe1->next=pe->next;delete pe;}}break;default :break;}}void setfree(){ 释放进程int chose;cout<<"选择一个要释放的任务:";cin>>chose;area*p7=usedhead,*p2;while( p7!=NULL) { //寻找有无此进程if( p7->sign!=chose ){p2=p7;p7=p7->next;}else break;}if(p7==NULL){cout<<"没有此进程,释放内存失败,返回修改!"<<endl;return;}inserfree(p7);//将其释放的内存插入空闲块中if(p7==usedhead &&p7->next==NULL)usedhead=NULL;else{if(p7->next==NULL){p2->next=NULL;delete p7;}//将次进程从已分配表中删除else {if(p7==usedhead){usedhead=p7->next;delete p7;}else {p2->next=p7->next;delete p7;}}}cout<<"成功释放所选任务的内存!当前内存状况为:"<<endl;print(freehead);print(usedhead);cout<<endl;}void inserused(area *p3,int num,int need){//将新项插入已分配表中area*p5;if(usedhead==NULL){p5=new area;p5->start=p3->start;p5->len=need;p5->sign=num;p5->end=p3->start+need;p5->next=NULL;usedhead=p5; }else{p5=new area;p5->start=p3->start;p5->len=need;p5->sign=num;p5->end=p3->start+need;p5->next=usedhead;usedhead=p5;}}void correct(area*p3,int need1){修改列表p3->len=p3->len-need1;p3->start=p3->start+need1;}void create(){ 创建地址长度area* p1;p1=new area;p1->start=0;p1->end=999;p1->len=999;p1->sign=0;p1->next=NULL;freehead= p1;}void ask1(area*freehead){//读文件初始化,只用一次int num,need;area*p3=freehead;ifstream infile("123.TXT");while(infile>>num){infile>>need;if(p3->len<need){cout<<"内存不足,分配失败!"<<endl;return;}elseinserused(p3,num,need);correct(p3,need);}}void ask(area*freehead){申请内存int num,need;area*p3=freehead,*p31=freehead;cout<<"input num and need! "<<endl;cin>>num;cin>>need;while( p3!=NULL){if(p3->len<need){p31=p3;p3=p3->next;}else break;}if(p3==NULL){cout<<"内存不足,分配失败!"<<endl;return;}inserused(p3,num,need);correct(p3,need);freehead=delempty();cout<<"成功分配申请,当前内存状况为:"<<endl;print(freehead);print(usedhead);cout<<endl;}void print(area*pp){显示页面area*p;p=pp;cout<<"────────────────────────────\n";if(p==NULL){cout<<"empty list!"<<endl;cout<<"────────────────────────────\n";return;}elsedo{cout<<"start:"<<p->start<<" end:"<<p->end<<" len:"<<p->len<<" sign:"<<p->sign<<endl;p=p->next;}while(p!=NULL);cout<<"────────────────────────────\n";}int main(){ int yourchose,flag1=0,flag2=0;int what;cout<<">>>>现在初始化内存>>>>>>>\n";cout<<"请选择:1.手动初始化 2.读取文件初始化:";cin>>flag2;create();if(flag2==2)ask1(freehead);cout<<"内存初始状态为:\n";print(freehead);print(usedhead);cout<<endl;cout<<"-------------菜单选项------------------\n";cout<<"1.申请内存 2.释放作业的内存\n";cout<<"3.查看空闲块链 4.查看已分配块链\n";cout<<"5.查看内存状态0.退出\n";cout<<"---------------------------------------"<<endl;;while(flag1==0){ cout<<"-----请选择操作---- :";cin>>yourchose;switch(yourchose){ case 1: cout<<"选择哪种方式?1.最先适应2.最优适应: ";cin>>what;if(what==1)listID();else listlen();ask(freehead);break;case 2:setfree();.释放作业的内存break;case 3:print(freehead);查看空闲块链break;case 4:print(usedhead);查看已分配块链\break;case 5: print(freehead);查看内存状态print(usedhead);break;case 0:flag1=1;退出break;default: break;}}return 0;}六、总结与体会在一开始老师布置这次的实验题目时,自己根本不知道要干什么,因为在上课时对动态分区分配这节内容不是太了解,所以在上机时不知道如何下手,后来,将本章内容反复的看了几遍之后,终于有了自己的思路。

合集下载

3用C语言模拟实现可变式分区存储管理

3用C语言模拟实现可变式分区存储管理

3用C语言模拟实现可变式分区存储管理可变式分区存储管理是一种动态分配内存空间的方式,它能够根据进程的内存需求来动态地分配和回收内存空间,提高内存的利用率。

在C语言中,我们可以使用指针和数据结构来模拟实现可变式分区存储管理。

1.使用结构体来表示内存块首先,我们可以定义一个结构体来表示每个内存块的属性,包括起始地址、大小、以及是否被占用等信息。

```cstruct Blockint start_address;int size;int is_allocated; // 0代表未分配,1代表已分配};```2.初始化内存空间接下来,我们可以定义一个数组来表示整个内存空间,该数组的每个元素都是一个 Block 结构体,表示一个内存块。

在程序开始时,我们可以初始化一个 Block 数组,表示整个内存空间的初始状态。

```c#define TOTAL_SIZE 1024 // 内存总大小struct Block memory[TOTAL_SIZE];void init_memormemory[0].start_address = 0;memory[0].size = TOTAL_SIZE;memory[0].is_allocated = 0;```3.分配内存空间当进程需要分配内存空间时,可变式分区存储管理会选择一个合适的内存块来分配给该进程。

我们可以定义一个函数来实现分配内存的过程。

```cint allocate_memory(int size)int i;for (i = 0; i < TOTAL_SIZE; i++)if (!memory[i].is_allocated && memory[i].size >= size)//找到未分配且大小足够的内存块memory[i].is_allocated = 1;memory[i].size -= size;return memory[i].start_address;}}//没有找到合适的内存块return -1;```4.回收内存空间当进程释放已分配的内存空间时,我们需要回收这部分内存,使其变为未分配状态。

动态分区分配方式的模拟

动态分区分配方式的模拟

动态分区分配方式的模拟动态分区分配方式是计算机中内存管理的一种重要方式。

在动态分区分配方式中,内存空间被分割为多个不同大小的分区,每个分区可以被进程占用。

当一个进程需要内存时,系统会为其分配一个适当大小的分区,进程结束后,该分区将会被释放出来供其他进程使用。

为了更好地理解动态分区分配方式的原理和实际运作,可以通过模拟的方法来观察和分析。

下面是一个简单的动态分区分配方式的模拟过程:假设我们有一块容量为6400KB的内存,要模拟分配4个进程的情况。

这4个进程的内存需求分别是1000KB,2000KB,500KB和300KB。

首先,我们可以将内存划分为几个分区,每个分区的大小根据需要进行调整。

可以设置整块内存为一块分区(大小为6400KB),或者划分成多个较小的分区。

由于这里有4个进程需要分配内存,我们可以为它们设置4个分区,分别为P1,P2,P3和P41.初始状态:内存:[6400KB](未分配)进程:P1,P2,P3,P4(空)2.分配P1:内存:[1000KB](P1)、[5400KB](未分配)进程:P1,P2,P3,P4P1占用了1000KB的内存,剩余空间为5400KB。

3.分配P2:内存:[1000KB](P1)、[2000KB](P2)、[3400KB](未分配)进程:P1,P2,P3,P4P2占用了2000KB的内存,剩余空间为3400KB。

4.分配P3:内存:[1000KB](P1)、[2000KB](P2)、[500KB](P3)、[2900KB](未分配)进程:P1,P2,P3,P4P3占用了500KB的内存,剩余空间为2900KB。

5.分配P4:内存:[1000KB](P1)、[2000KB](P2)、[500KB](P3)、[300KB](P4)、[2600KB](未分配)进程:P1,P2,P3,P4P4占用了300KB的内存,剩余空间为2600KB。

在模拟的过程中,我们可以看到进程在内存中的分配情况和未分配内存的变化。

动态分区存储管理方式的主存分配回收总结

动态分区存储管理方式的主存分配回收总结

动态分区存储管理方式的主存分配回收总结动态分区存储管理是一种常见的主存分配回收技术,它通过动态创建并分配大小不等的存储块来管理主存空间,以满足不同进程的需求。

这种管理方式在操作系统中起着至关重要的作用,因此本文将对动态分区存储管理的主存分配回收进行总结,从原理、特点、优缺点及其在实际应用中的情况进行阐述。

一、原理动态分区存储管理是基于分区的主存管理机制,它将主存空间划分为多个不等大小的分区,每个分区可以被分配给一个进程使用。

当系统收到一个新进程的请求时,它会根据需要的主存大小为进程分配一个合适大小的分区。

当进程执行完毕,系统会回收该进程所占用的分区,使得该空间可以再次被分配给其他进程使用。

在动态分区存储管理中,主要有两种分配方式:首次适应算法和最佳适应算法。

首次适应算法是从第一个满足大小要求的分区开始进行分配;而最佳适应算法是从所有满足大小要求的分区中选择最小的分区进行分配。

这两种分配方式都有自己的优点和局限性,但它们都是基于动态分区存储管理的基本原理。

二、特点1.灵活性动态分区存储管理可以根据进程的需求动态地分配和回收主存空间,提高了主存的利用率和效率。

进程可以根据需要申请和释放主存空间,而无需预先分配固定大小的空间。

2.节省空间动态分区存储管理可以尽可能地利用主存中的碎片空间,减少了外部碎片的浪费。

这种管理方式能够充分利用主存空间,提高了主存的利用率。

3.多样性动态分区存储管理可以适应不同大小的进程需求,能够根据进程的大小灵活地进行分区分配,满足了不同进程的需求。

三、优缺点1.优点(1)提高了主存的利用率和效率。

(2)灵活地分配和回收主存空间,满足不同进程的需求。

(3)节省了主存空间,减少了碎片的浪费。

2.缺点(1)会产生外部碎片,影响了分区空间的利用率。

(2)分配和回收过程中可能产生较大的开销,影响了系统的性能。

四、在实际应用中的情况动态分区存储管理在操作系统中得到了广泛的应用,特别是在多道程序设计和实时系统中。

操作系统实验一可变分区存储管理(含代码)

操作系统实验一可变分区存储管理(含代码)
3.掌握用指针实现链表和在链表上的基本操作。
(三)程序代码
#include<malloc.h>
#include<stdio.h>
#include<string.h>
#define new(type) (type *)malloc(sizeof(type))
typedef struct _map
{
unsigned int size;
}
}
else
{
if(addr+size==nextMap->address) //第三种情况
{
nextMap->address-=size;
nextMap->size+=size;
}
else //第四种情况
{
newMap=new(map);
newMap->address=addr;
newMap->size=size;
if(nextMap==m->head)
break;
}
prevMap=nextMap->prev;
if(nextMap!=m->head && prevMap->address+prevMap->size==addr) //第一种情况
{
prevMap->size+=size;
if(addr+size==nextMap->address) //第二种情况
prevMap->next=newMap;
newMap->prev=prevMap;
newMap->next=nextMap;

实验三 动态分区存储管理

实验三 动态分区存储管理

实验三存储管理动态分区存储管理
实验目的
•熟悉并掌握动态分区分配的各种算法。

•熟悉并掌握动态分区中分区回收的各种情
况,并能够实现分区合并。

实验内容及要求
•用高级语言模拟实现动态分区存储管理,要求:
–分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至少一种。

熟悉并掌握各种算法的空闲区组织方式。

–分区的初始化——可以由用户输入初始分区的大小。

(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小)–分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。

–分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。

(注意:不存在的作业号要给出错误提示!)–分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)
实验报告要求
•实验报告应包含但不限于以下内容:–设计图(结构图/流程图)和源代码;
–使用的编程语言和系统环境;
–结果截图;
–对结果截图的解释性说明。

注意事项
•三个动态分区分配算法可以使用一套程序,差别只在空闲分区链(表)的排序策略。

•至少完成一个分配算法。

•需完成回收算法。

动态分区算法实验报告

动态分区算法实验报告

动态分区算法实验报告动态分区算法实验报告一、引言计算机操作系统是现代计算机系统中的核心组成部分,它负责管理计算机硬件资源,并提供各种服务。

内存管理是操作系统的重要功能之一,它负责管理计算机的内存资源,为进程提供运行环境。

在内存管理中,动态分区算法是一种常用的内存分配策略。

本实验旨在通过实践,深入了解动态分区算法的原理和实现。

二、实验目的1. 了解动态分区算法的基本原理和实现方式;2. 掌握动态分区算法的实验环境搭建和使用方法;3. 分析动态分区算法的优缺点,并比较不同算法的性能差异。

三、实验环境本实验使用C语言编程实现,实验环境如下:1. 操作系统:Windows 10;2. 开发工具:Visual Studio 2019;3. 编程语言:C语言。

四、实验过程1. 实验准备在开始实验之前,我们首先需要了解动态分区算法的基本原理。

动态分区算法根据进程的内存需求,将内存划分为若干个不同大小的分区,并按照进程的请求进行分配和释放。

常用的动态分区算法有首次适应算法、最佳适应算法和最坏适应算法等。

2. 实验设计本实验选择实现首次适应算法,并设计以下几个函数:- 初始化内存空间:初始化一块指定大小的内存空间,将其划分为一个个的分区,并设置分区的状态;- 分配内存:根据进程的内存需求,在内存空间中找到合适的分区进行分配,并更新分区的状态;- 释放内存:将已分配的内存空间进行释放,并更新分区的状态;- 显示内存状态:打印当前内存空间的分区状态。

3. 实验实现根据上述设计,我们使用C语言实现了动态分区算法的相关函数。

通过调用这些函数,我们可以模拟动态分区算法的运行过程,并观察分区的分配和释放情况。

4. 实验结果经过实验,我们得到了以下结果:- 动态分区算法可以有效地管理内存资源,根据进程的需求进行灵活的内存分配;- 首次适应算法在内存分配效率和速度方面表现良好,但可能会导致内存碎片的产生;- 释放内存时,及时合并相邻的空闲分区可以减少内存碎片的数量。

动态分区管理方式及动态分区算法

动态分区管理方式及动态分区算法一、动态分区概述在操作系统中,内存管理是一个非常重要的部分。

在实际的应用中,程序的内存需求是会发生变化的,因此需要一种灵活的内存管理方式来满足不同程序的内存需求。

动态分区管理方式应运而生,它可以根据程序的需求,灵活地分配和回收内存空间,是一种高效的内存管理方式。

二、动态分区管理方式动态分区管理方式是指将内存划分为多个大小不等的分区,每个分区都可以被分配给进程使用,当进程终止时,分区将被回收。

动态分区管理方式通常通过动态分区算法来实现,下面将介绍几种常见的动态分区算法。

三、首次适应算法首次适应算法是最简单和最直观的动态分区分配算法。

它的基本思想是在空闲分区链表中按照位置区域顺序查找第一个能够满足进程大小需求的空闲分区,并将其分配给进程。

首次适应算法的优点是实现简单,分区利用率较高,但缺点是会产生大量的不连续碎片。

四、最佳适应算法最佳适应算法是在空闲分区链表中查找满足进程大小需求的最小空闲分区,并将其分配给进程。

最佳适应算法的优点是可以减少外部碎片,缺点是查找适合的空闲分区会花费较长的时间。

五、最坏适应算法最坏适应算法是在空闲分区链表中查找满足进程大小需求的最大空闲分区,并将其分配给进程。

最坏适应算法的优点是能够产生较小的碎片,但缺点是会导致剩余分区较多,影响分区利用率。

六、动态分区管理方式的优缺点动态分区管理方式相比于静态分区管理方式有很多优点,比如可以灵活地满足不同程序的内存需求,可以动态地合并和分割分区,提高了内存的利用率等。

但是动态分区管理方式也有一些缺点,比如会产生碎片,分配和回收内存的开销较大等。

七、结语动态分区管理方式及其算法在实际应用中有着广泛的应用,通过合理选择动态分区算法,可以提高内存的利用率,改善系统性能。

也需要注意动态分区管理方式可能产生的碎片问题,可以通过内存紧缩等手段来解决。

希望本文对读者有所帮助。

动态分区管理方式及动态分区算法八、碎片问题与解决方法在动态分区管理方式中,经常会出现碎片问题,包括内部碎片和外部碎片。

实验五动态分区分配算法的模拟

实验五动态分区分配算法的模拟为了更好地理解动态分区分配算法的工作原理,我们可以进行一次模拟实验。

在实验中,我们将模拟一个内存分区,并使用动态分区分配算法来管理这些分区。

首先,让我们定义一个内存大小为1000字节的分区。

我们假设这个内存中包含几个已分配的分区和几个空闲的分区。

我们使用首次适应算法来进行分区的首次适应分配。

首先,我们将整个内存空间标记为空闲状态,并创建一个初始的空闲链表。

我们假设初始时只有一个空闲分区,大小为1000字节,起始地址为0。

现在,假设有一个进程请求分配一个250字节大小的内存空间。

我们首先检查空闲链表,找到一个大小大于等于250字节的空闲分区。

在这种情况下,我们发现第一个空闲分区的大小是1000字节,所以我们将它拆分成250字节的已分配分区和750字节的空闲分区。

我们在已分配分区上标记一个进程编号,并将空闲分区加入空闲链表。

接下来,假设我们的进程需要申请500字节的内存空间。

在这种情况下,我们需要查找一个大小大于等于500字节的空闲分区。

我们发现第一个可用的空闲分区大小是750字节,我们将它拆分为已分配的500字节和剩余的250字节的空闲分区。

然后,我们假设有进程释放了先前分配的250字节的内存空间。

当一个进程释放分配的内存空间时,我们需要合并相邻的空闲分区。

在这种情况下,释放的分区位于地址0,大小为250字节,并且其下一个分区是地址500,大小为500字节的空闲分区。

因此,我们将这两个分区合并为一个大小为750字节的空闲分区。

接下来,我们假设另一个进程将请求600字节的内存空间。

根据首次适应算法,我们将在第一个满足条件的空闲分区进行分配。

在这种情况下,我们将分配200字节的空闲分区和分配400字节的空闲分区拆分为600字节的已分配分区和空闲分区。

最后,假设一个进程请求200字节的内存空间。

根据首次适应算法,我们在第一个满足条件的空闲分区进行分配。

在这种情况下,我们将250字节的空闲分区拆分为200字节的已分配分区和50字节的空闲分区。

实验五 动态分区分配算法的模拟

实验五动态分区分配算法的模拟一、实验目的1、加深操作系统内存管理过程的理解2、掌握内存分配算法的基本应用二、实验任务请同学们用C/C++实现一个完整的(可变)动态分区管理器,包括分配,回收,分区碎片整理等。

希望同学们实现如下功能:n 初始化功能:内存状态设置为初始状态。

n 分配功能:要求至少使用两种算法,用户可以选择使用。

n 回收功能:n 空闲块的合并:即紧凑功能,用以消除碎片。

当做碎片整理时,需要跟踪分配的空间,修改其引用以保证引用的正确性。

n 显示当前内存的使用状态,可以使用表格或图形。

三、实验指导1.基本思想动态分区是指系统不预先划分固定分区,而是在装入程序的时候划分内存区域,使得为程序分配的分区大小恰好等于该程序的需求量,且分区的个数是动态的。

显然动态分区有较大的灵活性,较之固定分区能获得好的内存利用率。

2.数据结构动态分区管理可以用两种数据结构实现,一种是已分配区表和空闲区表,也就是用预先定义好的系统空间来存放空间分配信息。

另一种也是最常用的就是空闲链表,由于对分区的操作是动态的,所以很难估计数据结构所占用的空间,而且空闲区表会占用宝贵的系统空间,所以提出了空闲链表的概念。

其特点是用于管理分区的信息动态生成并和该分区在物理地址上相邻。

这样由于可以简单用两个空闲块之间的距离定位已分配空间,不仅节约了系统空间,而且不必维持已分配空间的信息。

本实验是要做一个模拟程序,来模拟动态分区算法的分配和回收过程,并不是真正的去分配和回收内存。

基本的模拟方法有两种:1、先从内存中申请一块存储区,对这块存储区进行模拟的分配和回收活动。

2、不申请存储区,自己定义一块虚拟的存储区,对这块存储区进行模拟的分配和回收活动,分配和回收仅仅是对数据结构的修改而已。

程序代码:#include<iostream>using namespace std;int FreePartition[100];//空闲分区块数组int FirstPartition[100];//首次适应算法数组int CycleFirstPartition[100];//循环首次适应算法数组int BestPartition[100];//最佳适应算法数组int WorstPartition[100];//最坏适应算法数组int ProcessNeed[100];//每个作业的大小int PartitionNum,ProcessNum;//分区块数,作业数//首次适应算法void First(){int i,j;char str;for(i=0;i<PartitionNum;i++){FirstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++)//找出第一块满足作业的分区for(j=0;j<PartitionNum;j++){if(ProcessNeed[i]>FirstPartition[j])continue;else{FirstPartition[j]-=ProcessNeed[i];//找到后把分区大小减去作业的大小 ? ? ? ? ? ? ?str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl;break;}}cout<<endl;cout<<"分配之后剩余情况:"<<endl;?for(i=0;i<PartitionNum;i++)cout<<FirstPartition[i]<<" ";cout<<endl<<endl;}//循环首次适应算法void CycleFirst(){int i,j=1;char str;for(i=0;i<PartitionNum;i++){CycleFirstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++)//for(j=0;j<PartitionNum;j++){j=j-1;while(j<PartitionNum)if(ProcessNeed[i]>CycleFirstPartition[j])//continue;j++;else{CycleFirstPartition[j]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl; break;}//j++;//cout<<j<<" ";if(j==PartitionNum && i!=ProcessNum){i=-1;}}}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<CycleFirstPartition[i]<<" ";cout<<endl<<endl;}//最佳适应算法void Best(){int i,j,k;char str;?for(i=0;i<PartitionNum;i++){BestPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++){k=0;for(j=0;j<PartitionNum;j++){//cout<<BestPartition[j]<<" ? "<<ProcessNeed[i]<<endl; if(BestPartition[j]>=ProcessNeed[i]){break;}}for(int n=0;n<PartitionNum;n++){if(BestPartition[n]<BestPartition[k] && BestPartition[n]>=ProcessNeed[i])//找最佳的 k=n;}BestPartition[k]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl;}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<BestPartition[i]<<" ";cout<<endl<<endl;}//最坏适应算法void Worst(){int i,j,k;char str;for(i=0;i<PartitionNum;i++){WorstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++){k=0;for(j=0;j<PartitionNum;j++){if(WorstPartition[j]>WorstPartition[k])//找到最大的分区k=j;}WorstPartition[k]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl;}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<WorstPartition[i]<<" ";cout<<endl<<endl;}void main(){int i;cout<<"输入分区块数:"<<endl;cin>>PartitionNum;cout<<"输入每个分区的大小:"<<endl;for(i=0;i<PartitionNum;i++)cin>>FreePartition[i];cout<<"输入作业数:"<<endl;cin>>ProcessNum;cout<<"输入每个作业的大小:"<<endl;for(i=0;i<ProcessNum;i++)cin>>ProcessNeed[i];cout<<"------------首次适应算法-----------------"<<endl; First();cout<<"------------循环首次适应算法-------------"<<endl; ?CycleFirst();cout<<"------------最佳适应算法-----------------"<<endl; Best();cout<<"------------最坏适应算法-----------------"<<endl; Worst();}。

可变分区存储管理实验报告

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

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

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

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

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

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

9.重置或退出。

三、实验结果
第一至四组数据测试采用搬家算法,第二至八组数据测试不采用搬家算法。

第一组测试数据:(测试内存错误输入) 选择搬家算法,内存大小:0KB/-50KB/空
第二组测试数据:(测试内存空间不够)选择搬家算法,内存大小:400KB
第三组测试数据:(测试是否采用最佳适应法)选择搬家算法,内存大小:200KB 第四组数据:(测试搬家算法)选择搬家算法,内存大小:400KB
第五组数据至第八组数据:不采用搬家算法,内存大小:分别与第一至第四组数据相同,操作过程:分别与第一至第四组数据相同。

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