实验五 动态分区存储管理

合集下载

动态分区管理实验报告

动态分区管理实验报告

实验五动态分区管理模拟实验报告关键问题:写一动态分区管理程序,使其内存分配采用最优适应分配算法。

设计思路:在空闲分区链中找最适合的空闲块,使内存碎片尽量的减少!根据最佳适应算法原理,在内存分配函数ffallocation()中,增加记录适合空白块的标记sp,然后拿当前空白块fp减去后jl的后的大小和它后面的另一空白块sp减去jl的大小相比较。

如果前者大于后者,且后者的空白区大于jl的大小,则当前空白块为sp,否则继续往后比较,直到空闲分区链末尾!则当前空白块为最适合的空白块!然后就把当前空白块分配给作业。

其他部分的代码与实例相同!实现的关键代码://------------------------------------------------------------------- //有两个链:空白块链及作业链.空白块链描述空白块,链首指针freep,初始为一大块空白块.//作业链按从高址到低址的顺序链接,链首指针jobp//为作业jn分配jl大小内存,起始地址为javoid ffallocation(int jl,char jn[10],int* ja){mat* jp=NULL;//作业链当前节点mat* jp2=NULL;//新的作业节点mat* jp1=NULL;//freearea* fp=NULL;//当前空白块//修改部分 freearea* sp;//记录适合的空白块int i;*ja=-1;if (totalfree<jl) //剩余空间大小不能满足作业要求return;*ja=0;fp=freep;//取空白块链首块,将顺着链寻找第一块满足作业要求的块。

sp=freep;while (fp!=NULL){if (fp->freesize<jl){fp=fp->next;//当前空白块大小不满足要求sp=sp->next;}else //将当前空白块分配给作业{/*当当前空白块fp与它的下一块空白块sp相比较,如果它减去jl后大于下一空白块sp减去jl,且下一空白块sp大于等于jl,则当前空白块为sp;否则sp继续往后查找,直到空闲块查找完毕,然后当前空闲块为所要查找的适合空闲块!*/while(sp!=NULL){if((fp->freesize-jl>sp->freesize-jl)&(sp->freesize>=jl)){fp=sp;}else{sp=sp->next;}}// jobnumber++;totalfree=totalfree-jl;jp2=new mat;//申请一块作业节点空间//在节点上登记为该作业分配的内存空间// for (i=0;i<10;i++) (jp2->jobname)[i]=' ';i=-1;while(jn[++i])(jp2->jobname)[i]=jn[i];(jp2->jobname)[i]='\0';jp2->joblength=jl;jp2->jobaddress=fp->freeaddress;//登记该作业的起始地址*ja=jp2->jobaddress;//将节点jp2插入作业链jobp,按高址到低址的顺序。

实验五动态分区存储管理模拟

实验五动态分区存储管理模拟

实验五动态分区存储管理模拟一、实验目的深入了解可变分区存储管理式主存分配回收的实现。

二、实验预备知识可变分区存储管理式不预先将主存划分成几个区域,而把主存除操作系统占用区域外的空间看作一个大的空闲区。

当进程要求装入主存时,根据进程需要主存空间的大小查询主存各个空闲区,当从主存空间找到一个大于或等于该进程大小要求的主存空闲区时,选择其中一个空闲区,按进程需求量划出一个分区装入该进程。

进程执行完后,它所占的主存分区被回收,成为一个空闲区。

如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

这个实验主要需要考虑三个问题:(1)设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域;(2)在设计的数据表格基础上设计主存分配算法;(3)在设计的数据表格基础上设计主存回收算法。

首先,考虑第一个问题:设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域。

由于可变分区的大小是由进程需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收而变动。

总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。

由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。

由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一表格记录已分分区和空闲区,就会使表格操作繁琐。

主存分配时查找空闲区进行分配,然后填写已分分区表,主要操作在空闲区;某个进程执行完成后,将该分区变成空闲区,并将其与相邻空闲区合并,主要操作也在空闲区。

由此可见,主存分配和回收主要是对空闲区的操作。

这样,为了便于对主存空间的分配和回收,就建立两分区表记录主存使用情况,一表格记录进程占用分区的“已分分区表”;一是记录空闲区的“空闲区表”。

这两表的实现法一般有两种,一种是链表形式,一种是顺序表形式。

在实验中,采用顺序表形式,用数组模拟。

动态分区分配存储管理系统

动态分区分配存储管理系统

动态分区分配存储管理系统一、设计目的与内容用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法1)首次适应算法2)循环首次适应算法1.内存中有0-100M的空间为用户程序空间,最开始用户空间是空闲的。

2.作业数量、作业大小、进入内存时间、运行时间需要通过界面进行输入。

3.可读取样例数据(要求存放在外部文件中)进行作业数量、作业大小、进入内存时间、运行时间的初始化。

4.根据作业进入内存的时间,采用简单的先进先出原则进行从外存到内存的调度,作业具有等待(从外存进入内存执行)、装入(在内存可执行)、结束(运行结束,退出内存)三种状态。

5.能够自动进行内存分配与回收,可根据需要自动进行紧凑与拼接操作。

二、算法的基本思想1、定义基本结构:1作业结构:typedefstructJOB{intnum;//作业号intsize;//作业大小intctime;//作业进入时间intrtime;//作业运行时间intstate;//作业状态}Job;2)分区结构:typedefstructDuLNode{intID;//分区号intstart;//开始地址intsize;//大小intstate;//0=尚未使用1=使用2=释放structDuLNode*prior;〃前驱指针structDuLNode*next;//后即指针}DuLNode,*DuLinkList;2、基本操作:intFirstfit(int);//首次适应算法intNext_fit(int);//循环首次适应算法voidshowJob(int);//显示作业表voidshowPartiton(DuLinkList);//显示分区表DuLinkListInitpartitionList(DuLinkList&p);//初始化voidhuishou(DuLinkListpl3,DuLinkList&pl);//回收函数intPutin(int&口);//输入函数,输入作业相关信息3、首次适应算法空闲分区链以地址递增的次序链接,分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,取消的空闲分区仍留在空闲链中。

实验五 存储管理(实验报告格式)

实验五 存储管理(实验报告格式)

实验五:存储管理一、实验目的(1)熟悉内存空闲分区的分配方式;(2)理解动态分区存储管理方式;(3)掌握动态分区的分配与回收的过程。

二、实验环境微型计算机,Ubuntu Linux10.04 ,gedit,gcc三、实验内容根据流程图和参考程序,完成模拟内存分配和回收过程。

内存空间大小为100,进程数为5,每个进程所需空间为随机产生,大小为1~20,编制程序,首先对5个进程进行内存分配,然后回收指定的进程空间,并进行适当的空闲分区合并操作,要求每次操作结束后都能显示当前的内存分配情况。

四、实验结果截图一截图二截图三五、源代码#include<stdio.h>#include<malloc.h>typedef struct MEMORY_BLOCK{int name; //进程名int address; //起始地址int length; //长度int flag; //标志,表示该块是否被分配。

struct MEMORY_BLOCK *next; //指向下一个进程}MEMORY_BLOCK;#define NUM 5#define LEN sizeof(MEMORY_BLOCK)void allocation(MEMORY_BLOCK *Header,int name,int length_p){ MEMORY_BLOCK *temp,*t,*tt;int minsize=2; //不可切割的分区阈值while(t!=0){if(t->length>length_p&&t->flag==0) break;t=t->next;}if(t->length-length_p>minsize){ //分割temp=(MEMORY_BLOCK*)malloc(LEN);temp->name=-1;temp->flag=0;temp->length=t->length-length_p;temp->address=t->address+length_p;t->name=name;t->flag=1;t->length=length_p;temp->next=t->next;t->next=temp;}else{ //直接分配t->name=name;t->flag=1;}}void reclaim(int processname, MEMORY_BLOCK *Header){ MEMORY_BLOCK *temp,*t,*tt;temp=t;while(t->name!=processname){temp=t;t=t->next;}if(t->next!=NULL){ //t非尾结点if(temp->flag==0&&t->next->flag==0){ //左右为空temp->name=-1;temp->length=temp->length+t->length+t->next->length;tt=t->next;temp->next=tt->next;}else if(temp->flag==0){ //左为空temp->name=-1;temp->length=temp->length+t->length;temp->next=t->next;}else if(t->next->flag==0){ //右为空t->name=-1;t->length=t->length+t->next->length;t->flag=0;tt=t->next;t->next=tt->next;}else{ //左右不为空t->name=-1;t->flag=0;}else{ //t是尾结点if(temp->flag==0){ //左为空temp->name=-1;temp->length=temp->length+t->length;temp=t->next;}else{ //左不为空t->name=-1;t->flag=0;}}}void main(){ //主函数int length_p,i,processname;MEMORY_BLOCK *Header,*t;Header=(MEMORY_BLOCK*)malloc(LEN); //初始化存储空间Header->name=-1;Header->address=0;Header->length=100;Header->flag=0;Header->next=NULL;srand((int)time(0));for(i=1;i<=NUM+1;i++){length_p=rand()%20+1; //随机产生进程所需存储空间,至少为1allocation(Header,i,length_p);}printf("当前内存分配情况:\n");t=Header;while(t!=0){printf("process_name:%d,address:%d,length:%d,flag:%d\n",t->name,t->address,t->length,t->flag);t=t->next;}printf("请输入回收的进程号(输入0结束):\n");scanf("%d",&processname);while(processname!=0){printf("回收process name %d\n",processname);reclaim(processname,Header);printf("当前内存分配情况:\n");t=Header;while(t!=0){printf("process_name:%d,address:%d,length=%d,flag=%d\n", t->name, t->address, t->length,t->flag);t=t->next;}。

答案_实验五 存储管理(二)

答案_实验五 存储管理(二)

实验五存储管理(二)学号:姓名:班级:实验目的:1. 了解虚拟存储器。

2. 掌握分页存储管理的原理,熟悉段式存储和段页式存储管理。

3. 掌握常用的页面置换算法。

实验内容:一、选择:1.可变分区方式常用的主存分配算法中,(C)总是找到能满足作业要求的最大空闲区分配A、最佳适应算法B、首次适应算法C、最坏适应算法D、循环首次适应算法2.下列(A )存储方式不能实现虚拟存储器A、分区B、页式C、段式D、段页式3.操作系统处理缺页中断时,选择一种好的调度算法对主存和辅存中的信息进行高效调度尽可能地避免(D)A、碎片B、CPU空闲C、多重中断D、抖动4.分页式存储管理的主要特点是(C)A、要求处理缺页中断B、要求扩充主存容量C、不要求作业装入到主存的连续区域D、不要求作业全部同时装人主存5.LRU页面调度算法淘汰(B)的页A、最近最少使用B、最近最久未使用C、最先进入主存D、将来最久使用6.分区管理要求对每一个作业都分配(A)的主存单元A、地址连续B、若干地址不连续的C、若干连续的页D、若干不连续的帧7.在存储管理中,采用覆盖与交换技术的目的是(A)A、节省主存空间B、物理上扩充主存容量C、提高CPU的效率D、实现主存共享8.分页虚拟存储管理中,缺页中断时,欲调度一页进入主存中,内存己无空闲块,如何决定淘汰已在主存的块时,(B)的选择是很重要的A、地址变换B、页面调度算法C、对换方式D、覆盖技术9.(D)存储管理兼顾了段式在逻辑上清晰和页式在存储管理上方便的优点A、分段B、分页C、可变分区方式D、段页式10.在固定分区分配中,每个分区的大小是(C)A、随作业长度变化B、相同C、可以不同但预先固定D、可以不同但根据作业长度固定11.下述(B)页面置换算法会产生Belady现象A、最佳置换算法B、先进先出算法C、LRU算法D、Clock算法12.在一个分页式存储管理系统中,页表的内容为:若页的大小为4KB,则地址转换机构将相对地址0转换成的物理地址是(A)。

动态分区分配操作系统操作方法实验步骤

动态分区分配操作系统操作方法实验步骤

动态分区分配操作系统操作方法实验步骤1.引言1.1 概述概述部分:在计算机系统中,动态分区分配是一种重要的操作系统操作方法。

它是指在运行时根据进程的内存需求动态地将系统内存分配给进程,以实现内存资源的高效利用。

动态分区分配操作方法在现代操作系统中被广泛应用,例如Windows、Linux等。

通过合理的动态分区分配策略,可以提升系统的性能和资源利用率。

本文将对动态分区分配操作系统操作方法进行详细介绍和实验步骤的说明。

首先,我们将介绍动态分区分配的背景和意义,包括其在操作系统中的作用和应用场景。

其次,我们将详细讨论实验的具体步骤,包括如何进行动态分区分配操作、如何测试相关的性能指标等。

本文的目标是帮助读者了解动态分区分配操作系统操作方法的基本原理和实践技巧。

同时,通过实际操作和实验验证,读者将能够更好地理解动态分区分配的概念和操作过程,提升对操作系统的理解和应用能力。

在接下来的章节中,我们将分别介绍动态分区分配操作系统操作方法的背景和实验步骤,并给出相应的实例和案例分析。

最后,我们将对实验结果进行总结和展望,探讨动态分区分配操作方法的发展前景和可能的研究方向。

通过本文的阅读和实验操作,读者将能够对动态分区分配操作系统操作方法有一个全面的了解,为进一步研究和应用提供基础和指导。

同时,我们也欢迎读者对本文内容进行补充和扩展,以促进相关领域的进一步发展和应用。

1.2 文章结构文章结构部分的内容可以从以下角度进行描述:文章结构是指整篇文章的组织框架和内容安排。

合理的文章结构可以使读者更好地理解文章的主题和内容,帮助读者快速找到所需信息并形成完整的认识。

本文将按照以下结构进行论述:1. 引言:在引言部分,我们将对动态分区分配操作系统操作方法的背景和意义进行介绍,明确文章的目的和重要性。

2. 正文:正文是文章的核心部分,将分为两个要点进行叙述。

2.1 第一个要点:动态分区分配操作系统操作方法。

首先,我们将对动态分区分配的背景进行介绍,解释其在操作系统中的应用和意义。

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

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

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

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

首先,让我们定义一个内存大小为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();}。

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告DOC.doc

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告DOC.doc

计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号:2一、实验目的深入理解动态分区存储管理方式下的内存空间的分配与回收。

二、实验内容编写程序完成动态分区存储管理方式下的内存分配和回收的实现。

具体内容包括:确定用来管理内存当前使用情况的数据结构;采用首次适应算法完成内存空间的分配;分情况对作业进行回收;编写主函数对所做工作进行测试。

三、实验原理分配:动态分区存储管理方式把内存除OS占用区域外的空间看作一个大的空闲区。

当作业要求装入内存时,根据作业需要内存空间的大小查询内存中各个空闲区,当从内存中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业要求划出一个分区装入该作业。

回收:作业执行完后,它所占用的内存空间被收回,成为一个空闲区。

如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

四、实验方法实现动态分区的分配与回收,主要考虑三个问题:第一、设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域(利用结构体类型数组来保存数据);第二、在设计的数据表格基础上设计内存分配算法(采用首次适应算法找合适的分区(对空闲分区表进行排序),分配时要考虑碎片问题);第三、在设计的数据表格基础上设计内存回收算法(分四种情况进行回收(上邻、下邻、上下邻和无相邻分区)。

五、实验步骤第一,设计记录内存使用情况的数据表格●已分配分区表:起始地址、长度、标志(0表示“空表项”,1表示“已分配”)●空闲分区表:起始地址、长度、标志(0表示“空表项”,1表示“未分配”)struct used_table {float address; //已分分区起始地址float length; //已分分区长度,单位为字节int flag; //已分配表区登记栏标志,用0表示空栏目,char zuoyename;}; //已分配区表Struct free_table[ {float address; //空闲分区起始地址float length; //空闲分区长度,单位为字节int flag; //空闲分区表登记栏目用0表示空栏目,1表示未配}; //空闲分区表第二,在设计的表格上进行内存分配●首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。

动态分区分配存储管理系统

动态分区分配存储管理系统

动态分区分配存储管理系统一、设计目的与内容用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法1)首次适应算法2)循环首次适应算法1.内存中有0-100M 的空间为用户程序空间,最开始用户空间是空闲的。

2.作业数量、作业大小、进入内存时间、运行时间需要通过界面进行输入。

3.可读取样例数据(要求存放在外部文件中)进行作业数量、作业大小、进入内存时间、运行时间的初始化。

4.根据作业进入内存的时间,采用简单的先进先出原则进行从外存到内存的调度,作业具有等待(从外存进入内存执行)、装入(在内存可执行)、结束(运行结束,退出内存)三种状态。

5.能够自动进行内存分配与回收,可根据需要自动进行紧凑与拼接操作。

二、算法的基本思想1、定义基本结构:1 作业结构:typedef struct JOB {int num; //作业号int size; //作业大小int ctime;//作业进入时间int rtime;//作业运行时间int state; //作业状态}Job2)分区结构:typedef struct DuLNode {int ID; int start; int size;//分区号//开始地址//大小//0= 尚未使用1=使用2=struct DuLNode *prior;// 前驱指针struct DuLNode *next; // 后即指针}DuLNode, * DuLinkList;3、首次适应算法空闲分区链以地址递增的次序链接,分配内存时,从链首开始顺序查找,直至找到一个大 小能满足要求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存空间分配 给请求者,取消的空闲分区仍留在空闲链中。

若从链首直至链尾都不能找到一个能满足要求 的分区,则此次内存分配失败,返回。

4、循环首次适应算法在为进程分配内存空间时, 不再是每次都从链首开始查找, 而是从上次找到的空闲分区的 下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块与请求大小 相等的内存空间分配给作业。

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号:2一、实验目的深入理解动态分区存储管理方式下的内存空间的分配与回收。

二、实验内容编写程序完成动态分区存储管理方式下的内存分配和回收的实现。

具体内容包括:确定用来管理内存当前使用情况的数据结构;采用首次适应算法完成内存空间的分配;分情况对作业进行回收;编写主函数对所做工作进行测试。

三、实验原理分配:动态分区存储管理方式把内存除OS占用区域外的空间看作一个大的空闲区。

当作业要求装入内存时,根据作业需要内存空间的大小查询内存中各个空闲区,当从内存中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业要求划出一个分区装入该作业。

回收:作业执行完后,它所占用的内存空间被收回,成为一个空闲区。

如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

四、实验方法实现动态分区的分配与回收,主要考虑三个问题:第一、设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域(利用结构体类型数组来保存数据);第二、在设计的数据表格基础上设计内存分配算法(采用首次适应算法找合适的分区(对空闲分区表进行排序),分配时要考虑碎片问题);第三、在设计的数据表格基础上设计内存回收算法(分四种情况进行回收(上邻、下邻、上下邻和无相邻分区)。

五、实验步骤第一,设计记录内存使用情况的数据表格λ已分配分区表:起始地址、长度、标志(0表示“空表项”,1表示“已分配”)λ空闲分区表:起始地址、长度、标志(0表示“空表项”,1表示“未分配”)struct used_table { float address;//已分分区起始地址float length;//已分分区长度,单位为字节int flag;//已分配表区登记栏标志,用0表示空栏目,char zuoyename;};//已分配区表Struct free_table[ { float address;//空闲分区起始地址float length;//空闲分区长度,单位为字节int flag;//空闲分区表登记栏目用0表示空栏目,1表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。

实验五 动态分区分配方式内存管理模拟

实验五 动态分区分配方式内存管理模拟

实验五动态分区分配方式内存管理模拟一、实验目的1)掌握连续分配方式内存管理理论2)掌握动态分区分配方式内存管理理论二、实验原理动态分区分配:根据进程的实际需要,动态地创建分区为之分配内存空间,在实现动态分区分配时,将涉及分区分配中所使用的数据结构,分区分配算法和分区的分配与回收操作等问题。

1)分区分配中的数据结构空闲分区表:一个数据表,用于记录每个空闲块的情况,如起始地址、大小、使用情况等;空闲分区链表:把所有的空闲分区链接成一个链表,便于内存空间查看与分配回收。

2)分配算法首次适应法:空闲分区按首地址递增次序组织,每次查找时从链首出发,寻找满足要求的内存块。

循环首次适应算法:空闲分区按首地址递增次序组织,每次从上次查找的下一个空闲块开始查找,直到找到满足要求的内存块。

最佳适应法:空闲分区按空闲分区大小址递增次序组织,每次查找时从链首出发,寻找满足要求的最小内存块进行分配。

最坏适应法:空闲分区按空闲分区大小递减次序组织,每次查找时直接判断最大空闲分区是否满足要求。

3)内存分配过程利用分配算法找到满足要求的内存块,设请求的内存大小为size:若找到的空闲分区的大小等于size,完全分配;若找到的空闲分区大小大于size,且一分为二后,剩余大小小于1K,则不再分割,作为整体进行分配;否则一分为二,剩余部分仍然作为空闲分区存在;若无满足要求空闲分区,则分配失败4)内存回收根据释放区首址和大小,查找空闲分区表/链表,判断是否有相邻的空闲分区存在:释放区与前空闲区相邻:将释放区与前空闲区合并为一个空闲区。

其首址仍为前空闲区首址,大小为释放区大小与空闲区大小之和。

释放区与前后两个空闲区相邻:将这三个区合为一个空闲区,其首址为前空闲区首址,大小为这三个区大小之和,并取消原后空闲区表目。

释放区与后空闲区相邻:则把释放区合并到后空闲,首地址为释放区首地址,大小为二者大小之和。

释放区不与任何空闲区相邻:将释放区作为一个空闲区,将其大小和首址插入到空闲区表的适当位置。

动态分区存储管理

动态分区存储管理
if(p->state == Free && p->size >= size) { // 找到要分配的空闲分区 if(p->size - size <= MINSIZE) { // 整块分配 p->state = Busy; p->taskId = taskId; } else { // 分配大小为 size 的区间 subAreaNode *node = (subAreaNode
p->nxt = pp->nxt; if(pp->nxt != NULL) {
pp->nxt->pre = p; } free(pp); } else if((p->pre != &subHead && p->pre->state == Free) && (p->nxt == NULL || p->nxt->state == Busy)) { // 情况 3:只合并上面的分区 pp = p; p = p->pre; p->size += pp->size; p->nxt = pp->nxt; if(pp->nxt != NULL) {
} else {
printf("
");
}
printf("\n");
p = p->nxt;
}
}
int main() {
int option, ope, taskId, size; // 初始化空闲分区链 intSubArea(); // 选择分配算法 while(1) {
printf("请选择要模拟的分配算法: 0 表示首次适应算法,1 表示最 佳适应算法\n");

实验五存储管理实验报告

实验五存储管理实验报告

计算机与信息技术学院综合性实验报告一、实验目的通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。

二、实验仪器或设备微型计算机、Linux操作系统、dev C++三、总体设计1、通过随机数产生一个指令序列,共320条指令。

其地址按下述原则生成:①50%的指令是顺序执行的;②25%的指令是均匀分布在前地址部分;③25%的指令是均匀分布在后地址部分;具体的实施方法是:A.在[0,319]的指令地址之间随机选取一起点M;B.顺序执行一条指令,即执行地址为M+1的指令;C.在前地址[0,M+1]中随机选取一条指令并执行,该指令的地址为M’;D.顺序执行一条指令,其地址为M’+1;E.在后地址[M’+2,319]中随机选取一条指令并执行;F.重复A—E,直到执行320次指令。

2、指令序列变换成页地址流,设:①页面大小为1K;②用户内存容量为4页到32页;③用户虚存容量为32K。

在用户虚存中,按每页存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:第0条~第9条指令为第0页(对应虚存地址为[0,9]);第10条~第19条指令为第1页(对应虚存地址为[10,19]);…………第310条~第319条指令为第31页(对应虚存地址为[310,319]);按以上方式,用户指令可组成32页。

3、计算并输出下述算法在不同内存容量下的命中率。

A. FIFO先进先出置换算法;B. LRU最近最久未使用置换算法;C. NUR最近未使用置换算法。

命中率=1-页面失效次数/页地址流长度在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。

4、相关定义(1)数据结构○1页面类型typedef struct /*页面结构*/{int pn,pfn,time;}pl_type;其中pn为页面号,pfn为页帧号,time为访问时间○2页帧控制结构struct pfc_struct{ /*页帧控制结构*/int pn,pfn;struct pfc_struct *next;};typedef struct pfc_struct pfc_type;pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;其中pfc_type pfc[total_vp]定义用户进程虚页控制结构*freepf_head为空闲页帧头的指针*busypf_head为忙页帧头的指针*busypf_tail忙页帧尾的指针(2)函数定义void initialize(int):初始化函数void FIFO(int):计算使用FIFO算法时的命中率void LRU(int):计算使用LRU算法时的命中率void NRU(int):计算使用NRU算法时的命中率(3)变量定义int a[total_instruction]:指令流数组int diseffect:页面失效次数int page[total_instruction]:每条指令所属页面号int offset[total_instruction]:每页装入10条指令后取模运算得出的页内偏移地址int total_pf:用户进程的内存页面数四、实验步骤按照流程图编写代码、并上机调试运行程序代码:#include <stdlib.h>#include <stio.h>#define TRUE 1#define FALSE 0#define INVALID -1#define total_instruction 320 /*指令流长*/#define total_vp 32 /*虚页长*/typedef struct /*页面结构*/{int pn,pfn,time;}pl_type;pl_type pl[total_vp]; /*页帧结构数组*/struct pfc_struct{ /*页帧控制结构*/int pn,pfn;struct pfc_struct *next;};typedef struct pfc_struct pfc_type;pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;int diseffect,a[total_instruction];int page[total_instruction],offset[total_instruction];void initialize(int);void FIFO(int);void LRU(int);void NRU(int);int main( ){int s,i;/*由于每次运行时进程号不同,故可用来作为初始化随机数队列的“种子”*/ srand(10*getpid());s=(float)319*rand( )/RAND_MAX+1;for(i=0;i<total_instruction;i+=4) /*产生指令队列*/{a[i]=s; /*任选一指令访问点m*/a[i+1]=a[i]+1; /*顺序执行一条指令*/a[i+2]=(float)a[i]*rand( )/RAND_MAX; /*执行前地址指令m' */a[i+3]=a[i+2]+1; /*顺序执行一条指令*/s=(float)(318-a[i+2])*rand( )/RAND_MAX+a[i+2]+2;}for (i=0;i<total_instruction;i++) /*将指令序列变换成页地址流*/{page[i]=a[i]/10;offset[i]=a[i]%10;}for(i=4;i<=32;i++) /*用户内存工作区从4个页帧到32个页帧*/{printf("%2d page frames ",i);void FIFO(int);void LRU(int);void NRU(int);printf("\n");}}void initialize(int total_pf) /*初始化相关数据结构*/ {int i;diseffect=0;for(i=0;i<total_vp;i++){ pl[i].pn=i;pl[i].pfn=INVALID;pl[i].time=-1;}for(i=0;i<total_pf-1;i++){ pfc[i].next=&pfc[i+1];pfc[i].pfn=i;} /*建立pfc[i-1]和pfc[i]之间的链接*/pfc[total_pf-1].next=NULL;pfc[total_pf-1].pfn=total_pf-1;freepf_head=&pfc[0]; /*空页面队列的头指针为pfc[0]*/ }void FIFO(int total_pf) /*先进先出算法*/int total_pf; /* 用户进程的内存页面数 */ { int i,j;pfc_type *p, *t;initialize(total_pf); /* 初始化相关页面控制用数据结构*/ busypf_head=busypf_tail=NULL: /* 忙页面队列头,队列尾链接 */for(i=0;i=total_instruction;i++){ if(p1[page[i]].pfn= =INVALID) /* 页面失效 */{ disaffect+=1; /* 失效次数 */if(freep_headf= =NULL) /* 无空闲页面 */{ p=busypf_head->next;p1[busypf_head->pn].pfn=INVALID;freepf_head=busypf_head; /*释放忙页面队列中的第一个页面*/ freepf_head->next=NULL:busypf_head=p;}p=freepf_head->next; /* 按FIFO方式调新页面入内存页面 */ freepf_head->next=NULL:freepf_head->pn=page[i];p1[page[i]].pfn=freepf_head->pfn;if(busypf_tail= =NULL)busypf_head=busypf_tail=freepf_head;else{ busypf_tail->next=freepf_head;busypf_tail=freepf_head;}freepf_head=p;}}printf(“FIFO:%6.4f”,1-(float)disaffect/320);}void LRU (int total_pf) /*最近最久未使用算法*/int total_pf;{ int min,minj,i,j,present_time;initialize(total_pf);present_time=0;for(i=0;i<total_instruction;i++){ if(p1[page[i]].pfn= =INVALID) /* 页面失效 */ { disaffect++;if(freepf_head= =NULL) /* 无空闲页面 */ { min=32767;for(j=0;j<total_vp;j++)if(min>p1[j].time&&p1[j].pfn !=INVALID){ min=p1[j].time;minj=j;}freepf_head=&pfc[p1[minj].pfn];p1[minj].pfn=INVALID;p1[min].time=-1;freepf_head->next=NULL;}p1[page[i]].pfn=freepf_head->pfn;p1[page[i]].time=present_time;freepf_head=freepf_head->next;}elsep1[page[i]].time=present_time;present_time++;}printf(“LRU:%6.4f”,1-(flaot)disaffect/320);}void NRU(int total_pf) /*最近未使用置换算法*/ int total_pf;{ int i,j,dp,cont_flag,old_dp;pfc_type *t;initialize(total_pf);dp=0;for(i=0;i<total_instruction;i++){ if(p1[page[i]].pfn= =INVALID) /* 页面失效 */ { diseffect++;if(freepf_head= =NULL) /* 无空闲页面 */ { cont_flag=TRUE;old_dp=dp;while(cont_flag)if(p1[dp].counter= =0 && p1[dp].pfn!=INVALID)cont_flag=FLASE;else{ dp++;if(dp= =total_vp)dp=0;if(dp= =old_dp)for(j=0;j<total_vp;j++)p1[j].counter=0;}freepf_head=&pfc[p1[dp].pfn];p1[dp].pfn=INVALID;freepf_head->next=NULL:}p1[page[i]].pfn=freepf_head->pfn;freepf_head=freepf_head->next;}elsep1[page[i]].counter=1;if(i%clear_period= =0)for(j=0;j<total_vp;j++)p1[j].counter=0;}printf(“NUR:%6.4f”,1-(float)disaffect/320);}void OPT(total_pf)int total_pf;{ int i,j,max,maxpage,d,dist[total_vp];pfc_type *t;initialize(total_pf);for(i=0;i<total_instruction;i++){ if(p1[page[i]].pfn= =INVALID){ diseffect++;if(freepf_head= =NULL){ for(j=0;j<total_vp;j++)if(p1[j].pfn !=INVALID)dist[j]=32767;elsedist[j]=0;d=1;for(j=i+1;j<total_instruction;j++){ if(p1[page[j]].pfn!=INVALID)dist[page[j]]=d;d++;}max=-1;for(j=0;j<total_vp;j++)if(max<dist[j]){ max=dist[j];maxpage=j;}freepf_head=&pfc[p1[maxpage].pfn];freepf_head->next=NULL;p1[maxpage].pfn=INVALID;}p1[page[i]].pfn=freepf_head->pfn;freepf_head=freepf_head->next;}}printf(“OPT:%6.4f”,1-(float)disaffect/320);}显示结果:4 page frames FIFO:0.4969 LRU:0.5000 NUR:0.50005 page frames FIFO:0.5188 LRU:0.5125 NUR:0.50626 page frames FIFO:0.5281 LRU:0.5188 NUR:0.53447 page frames FIFO:0.5406 LRU:0.5500 NUR:0.55628 page frames FIFO:0.5500 LRU:0.5719 NUR:0.55319 page frames FIFO:0.5625 LRU:0.5812 NUR:0.578110 page frames FIFO:0.5844 LRU:0.5969 NUR:0.596911 page frames FIFO:0.5938 LRU:0.6094 NUR:0.625012 page frames FIFO:0.6156 LRU:0.6281 NUR:0.659413 page frames FIFO:0.6375 LRU:0.6344 NUR:0.650014 page frames FIFO:0.6844 LRU:0.6625 NUR:0.650015 page frames FIFO:0.6844 LRU:0.6812 NUR:0.687516 page frames FIFO:0.7062 LRU:0.7062 NUR:0.709417 page frames FIFO:0.7094 LRU:0.7125 NUR:0.725018 page frames FIFO:0.7188 LRU:0.7281 NUR:0.734419 page frames FIFO:0.7281 LRU:0.7531 NUR:0.753120 page frames FIFO:0.7281 LRU:0.7656 NUR:0.759421 page frames FIFO:0.7812 LRU:0.7781 NUR:0.790622 page frames FIFO:0.7875 LRU:0.7937 NUR:0.812523 page frames FIFO:0.7960 LRU:0.8094 NUR:0.818724 page frames FIFO:0.8000 LRU:0.8219 NUR:0.821925 page frames FIFO:0.8344 LRU:0.8312 NUR:0.834426 page frames FIFO:0.8625 LRU:0.8438 NUR:0.859427 page frames FIFO:0.8625 LRU:0.8652 NUR:0.878128 page frames FIFO:0.8750 LRU:0.8656 NUR:0.881229 page frames FIFO:0.8844 LRU:0.8781 NUR:0.881230 page frames FIFO:0.8875 LRU:0.8875 NUR:0.890631 page frames FIFO:0.8875 LRU:0.8906 NUR:0.900032 page frames FIFO:0.9000 LRU:0.9000 NUR:0.9000五、结果分析与总结从上述结果可知,当内存页面数较少(4~5页面)时,5种算法的命中率差别不大,都是50%左右。

动态分区存储管理方式的主存分配回收实验参考

动态分区存储管理方式的主存分配回收实验参考

动态分区存储管理方式的主存分配回收实验报告一、实验目的深入了解动态分区存储管理方式的主存分配回收的实现。

二、实验要求编写程序完成动态分区存储管理方式的主存分配回收的实现。

实验具体包括:首先确定主存空间分配表;然后采用最优适应算法完成主存空间的分配,完成主存空间的回收;最后编写主函数对所作工作进程测试。

三、实验原理:存储管理中动态分区的管理方式。

四、实验程序设计1.数据结构◆已分分区表的数据结构定义#define n 10 //假定系统允许的最大作业数量为ntypedef struct used{float address; //已分分区起始地址float length; //已分分区长度,单位为字节CString flag; //已分配区表登记栏标志,用"0"表示空栏目,作业名表示使用}USED; //已分配区表USED used_table[n];◆空闲区表的数据结构定义#define m 10 //假定系统允许的空闲区表最大为mtypedef struct free{float address; //空闲区起始地址float length; //空闲区长度,单位为字节int flag; //空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配}FREE; //空闲区表FREE free_table[m];2.功能函数设计1)系统数据初始化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';2)分配函数void CExp3Dlg::allocate(CString J, float xk) //采用最优分配算法分配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) //未找到可用空闲区,返回{this->MessageBox("无可用空闲区");return;}/*找到可用空闲区,开始分配:若空闲区大小与要求分配的空间差小于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<m) //寻找空表目i++;if(i>=m) //无表目填写已分分区{MessageBox("无表目填写已分分区,错误");//修正空闲区表if(free_table[k].flag==0) //前面找到的是整个空闲区free_table[k].flag=1;else //前面找到的是某个空闲区的一部分free_table[k].length=free_table[k].length+xk;return;}else //修改已分配区表{used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;}return;}3)回收函数void CExp3Dlg::reclaim(CString J) //回收作业名为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的作业{MessageBox("找不到该作业");return;}//修改已分配区表used_table[s].flag='0';//取得归还分区的起始地址S和长度LS=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;//寻找回收分区的上下邻空闲区,上邻表目k,下邻表目jwhile(i<MMM&&(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<MMM)t++;if(t>=MMM) //空闲区表满,回收空间失败,将已分配区表复原{MessageBox("主存空闲表没有空间,回收空间失败");used_table[s].flag=J;return;}free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;}return;}4)按钮函数设计◆【分配】按钮void CExp3Dlg::OnButtonAlloc(){this->UpdateData(true);CString name;float size;name=this->m_EDIT_NAME;size=this->m_EDIT_SIZE;allocate(name,size);}◆【回收】按钮void CExp3Dlg::OnButtonReclaim(){this->UpdateData(true);CString name;name=this->m_EDIT_NAME;this->reclaim(name);}◆【显示分配区】按钮void CExp3Dlg::OnButtonAllocate(){CString str,xx;CListBox *L;L=&m_LIST_ALLOC;L->ResetContent();L->InsertString(0,"起始地址分区长度标志");for(int j=0;j<10;j++){str="";xx.Format("%-8.2f",used_table[j].address);str+=xx+" ";xx.Format("%-8.2f",used_table[j].length);str+=xx+" ";xx.Format("%s",used_table[j].flag);str+=xx;L->InsertString(j+1,str);}}◆【显示回收区】按钮void CExp3Dlg::OnButtonFree(){// TODO: Add your control notification handler code hereCString str,xx;CListBox *L;L=&m_LIST_FREE;L->ResetContent();L->InsertString(0,"起始地址分区长度标志");for(int j=0;j<MMM;j++){str="";xx.Format("%-8.2f",free_table[j].address);str+=xx+" ";xx.Format("%-8.2f",free_table[j].length);str+=xx+" ";xx.Format("%5d",free_table[j].flag);str+=xx;L->InsertString(j+1,str);}}3.界面设计本程序的界面力求简洁、友好,每一步需要用户操作的提示以及每一次用户操作产生的调度结果都以中文的形式显示在屏幕上,使用户对要做什么和已经做了什么一目了然。

实验五 动态分区存储管理系统模拟

实验五 动态分区存储管理系统模拟

实验五动态分区存储管理模拟一、实验目的深入了解可变分区存储管理方式主存分配回收的实现。

二、实验预备知识可变分区存储管理方式不预先将主存划分成几个区域,而把主存除操作系统占用区域外的空间看作一个大的空闲区。

当进程要求装入主存时,根据进程需要主存空间的大小查询主存内各个空闲区,当从主存空间找到一个大于或等于该进程大小要求的主存空闲区时,选择其中一个空闲区,按进程需求量划出一个分区装入该进程。

进程执行完后,它所占的主存分区被回收,成为一个空闲区。

如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

这个实验主要需要考虑三个问题:(1)设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域;(2)在设计的数据表格基础上设计主存分配算法;(3)在设计的数据表格基础上设计主存回收算法。

首先,考虑第一个问题:设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域。

由于可变分区的大小是由进程需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收而变动。

总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。

由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。

由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。

主存分配时查找空闲区进行分配,然后填写已分分区表,主要操作在空闲区;某个进程执行完成后,将该分区变成空闲区,并将其与相邻空闲区合并,主要操作也在空闲区。

由此可见,主存分配和回收主要是对空闲区的操作。

这样,为了便于对主存空间的分配和回收,就建立两张分区表记录主存使用情况,一张表格记录进程占用分区的“已分分区表”;一张是记录空闲区的“空闲区表”。

这两张表的实现方法一般有两种,一种是链表形式,一种是顺序表形式。

在实验中,采用顺序表形式,用数组模拟。

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

实验五动态分区存储管理一、实验目的深入了解采用动态分区存储管理方式的内存分配回收的实现。

通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉动态分区存储管理的内存分配和回收。

二、实验内容编写程序完成动态分区存储管理方式的内存分配回收。

具体包括:确定内存空间分配表;采用最优适应算法完成内存空间的分配和回收;编写主函数对所做工作进行测试。

三、设计思路整体思路:动态分区管理方式将内存除操作系统占用区域外的空间看成一个大的空闲区。

当作业要求装入内存时,根据作业需要内存空间的大小查询内存中的各个空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区。

如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

设计所采用的算法:采用最优适应算法,每次为作业分配内存时,总是把既能满足要求、又是最小的空闲分区分配给作业。

但最优适应算法容易出现找到的一个分区可能只比作业所需求的长度略大一点的情行,这时,空闲区分割后剩下的空闲区就很小以致很难再使用,降低了内存的使用率。

为解决此问题,设定一个限值minsize,如果空闲区的大小减去作业需求长度得到的值小于等于minsize,不再将空闲区分成己分分区和空闲区两部分,而是将整个空闲区都分配给作业。

内存分配与回收所使用的结构体:为便于对内存的分配和回收,建立两张表记录内存的使用情况。

一张为记录作业占用分区的“内存分配表”,内容包括分区起始地址、长度、作业名/标志(为0时作为标志位表示空栏目);一张为记录空闲区的“空闲分区表”,内容包括分区起始地址、长度、标志(0表空栏目,1表未分配)。

两张表都采用顺序表形式。

关于分配留下的内存小碎片问题:当要装入一个作业时,从“空闲分区表”中查找标志为“1”(未分配)且满足作业所需内存大小的最小空闲区,若空闲区的大小与作业所需大小的差值小于或等于minsize,把该分区全部分配给作业,并把该空闲区的标志改为“0”(空栏目)。

同时,在已分配区表中找到一个标志为“0”的栏目登记新装人作业所占用分区的起始地址,长度和作业名。

若空闲区的大小与作业所需大小的差值大于minsize。

则把空闲区分成两部分,一部分用来装入作业,另外一部分仍为空闲区。

这时只要修改原空闲区的长度,且把新装人的作业登记到已分配区表中。

内存的回收:在动态分区方式下回收内存空间时,先检查是否有与归还区相邻的空闲区(上邻空闲区,下邻空闲区)。

若有,则将它们合件成一个空闲区。

程序实现时,首先将要释放的作业在“内存分配表”中的记录项的标志改为“0”(空栏目),然后检查“空闲区表”中标志为‘1’(未分配)的栏目,查找是否有相邻的空闲区,若有,将之合并,并修改空闲区的起始地址和长度。

四、数据结构定义(1)已分配表的定义:struct{float address; //已分分区起始地址float length; //已分分区长度,单位为字节int flag; //已分配区表登记栏标志,"0"表示空栏目,实验中只支持一个字符的作业名}used_table[n]; //已分配区表(2)空闲分区表的定义:struct{float address; //空闲区起始地址float length; //空闲区长度,单位为字节int flag; //空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配}free_table[m]; //空闲区表(3)全局变量float minsize=5;#define n 10 //假定系统允许的最大作业数量为n#define m 10 //假定系统允许的空闲区表最大为m五、源程序代码#include <iostream.h>#include <iomanip.h>//全局变量float minsize=5;int count1=0;int count2=0;#define M 10 //假定系统允许的空闲区表最大为m#define N 10 //假定系统允许的最大作业数量为n//已分配表的定义struct{float address; //已分分区起始地址float length; //已分分区长度,单位为字节int flag; //已分配区表登记栏标志,"0"表示空栏目}used_table[N]; //已分配区表对象名//空闲区表的定义:struct{float address; //空闲区起始地址float length; //空闲区长度,单位为字节int flag; //空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配}free_table[M]; //空闲区表对象名//函数声明void initialize(void);int distribute(int, float);int recycle(int);void show();//初始化两个表void initialize(void){int a;for(a=0; a<=N-1; a++)used_table[a].flag=0; //已分配表的表项全部置为空表项free_table[0].address=1000;free_table[0].length=1024;free_table[0].flag=1; //空闲区表的表项全部为未分配}//最优分配算法实现的动态分区int distribute(int process_name, float need_length){int i, k=-1; //k用于定位在空闲表中选择的未分配栏float ads, len;int count=0;i=0;while(i<=M-1) //循环找到最佳的空闲分区{if(free_table[i].flag==1 && need_length <=free_table[i].length){count++;if(count==1||free_table[i].length < free_table[k].length)k=i;}i=i+1;}if(k!=-1){if((free_table[k].length-need_length)<=minsize) //整个分配{free_table[k].flag=0;ads=free_table[k].address;len=free_table[k].length;}else{ //切割空闲区ads=free_table[k].address;len=need_length;free_table[k].address+=need_length;free_table[k].length-=need_length;}i=0;//循环寻找内存分配表中标志为空栏目的项while(used_table[i].flag!=0){i=i+1;}if(i<=N-1) //找到,在已分配区表中登记一个表项{used_table[i].address=ads;used_table[i].length=len;used_table[i].flag=process_name;count1++;}else //已分配区表长度不足{if(free_table[k].flag == 0) //将已做的整个分配撤销{free_table[k].flag=1;free_table[k].address=ads;free_table[k].length=len;}else //将已做的切割分配撤销{free_table[k].address=ads;free_table[k].length+=len;}cout<<"内存分配区已满,分配失败!\n";return 0;}}else{cout <<"无法为该作业找到合适分区!\n";return 0;}return process_name;}int recycle(int process_name){int y=0;float recycle_address, recycle_length;int i, j, k; //j栏是下邻空闲区,k栏是上栏空闲区int x;//在内存分配表中找到要回收的作业while(y<=N-1&&used_table[y].flag!=process_name){ y=y+1;}if(y<=N-1) //找到作业后,将该栏的标志置为'0'{recycle_address=used_table[y].address;recycle_length=used_table[y].length;used_table[y].flag=0;count2++;}else //未能找到作业,回收失败{cout<<"该作业不存在!\n";return 0;}j=k=-1;i=0;while(!(i>=M||(k!=-1&&j!=-1))) //修改空闲分区表{if(free_table[i].flag==1){if((free_table[i].address+free_table[i].length)==recycle_address) k=i; //判断是否有上邻接if((recycle_address+recycle_length)==free_table[i].address)j=i; //判断是否有下邻接}i=i+1;}//合并空闲区if(k!=-1) //回收区有上邻接{if(j!=-1){ //回收区也有下邻接,和上下邻接合并free_table[k].length+=free_table[j].length+recycle_length;free_table[j].flag=0; //将第j栏的标记置为'0'}else //不存在下邻接,和上邻接合并free_table[k].length+=recycle_length;}else if(j!=-1){ //只有下邻接,和下邻接合并free_table[j].length+=recycle_length;free_table[j].address=recycle_address;}else{ //上下邻接都没有x=0;while(free_table[x].flag!=0)x=x+1; //在空闲区表中查找一个状态为'0'的栏目if(x<=M-1){ //找到后,在空闲分区中登记回收的内存free_table[x].address=recycle_address;free_table[x].length=recycle_length;free_table[x].flag=1;}else{ //空闲表已满,执行回收失败used_table[y].flag=process_name;cout<<"空闲区已满,回收失败!\n";return 0;}}return process_name;}void show() //程序执行时输出模拟的内存分配回收表{cout<<"+++++++++++++++++++++++++++++++++++++++\n ";cout<<"+++++++ 空闲区+++++++\n";cout<<"+++++++++++++++++++++++++++++++++++++++\n";for(int i=0;i<=count2;i++)if(free_table[i].flag!=0)cout<<"初始地址:"<<free_table[i].address<<" "<<"长度:"<<free_table[i].length<<" "<<"状态:"<<free_table[i].flag<<endl;cout<<"+++++++++++++++++++++++++++++++++++++++\n ";cout<<"+++++++ 已分配区++++++\n";cout<<"+++++++++++++++++++++++++++++++++++++++\n";for(int j=0;j<count1;j++)if(used_table[j].flag!=0)cout<<"初始地址:"<<used_table[j].address<<" "<<"长度:"<<used_table[j].length<<" "<<"作业名:"<<used_table[j].flag<<endl;}void main() //主函数调用各功能函数对所有工作进行测试{int choice; //用来选择将要进行的操作int job_name;float need_memory;bool exitFlag=false;cout<<" 动态分区分配方式的模拟\n";cout<<"************************************\n";cout<<"请选择操作类型:\n";initialize(); //开创空闲区和已分配区两个表while(!exitFlag){cout<<"********************************************\n";cout<<"** 1: 分配内存2: 回收内存**\n";cout<<"** 3: 查看分配0: 退出**\n";cout<<"********************************************\n";cout<<"请输入您的操作:";cin>>choice;switch(choice){case 0:exitFlag=true; //退出操作break;case 1:cout<<"请输入作业号和所需内存:";cin>>job_name>>need_memory;if(job_name!=0&&need_memory!=0)distribute(job_name, need_memory); // 分配内存else if(job_name==0)cout<<"作业号不能为零!\n请重新选择操作:\n";else if(need_memory==0)cout<<"内存分配数不能为零!\n请重新选择操作:\n";break;case 2:int ID;cout<<"请输入您要释放的作业号:";cin>>ID;if(ID!=0)recycle(ID); //回收内存elsecout<<"作业名不能为零!\n请重新选择操作:\n";break;case 3:show();break;}}}六、实验结果分析1. 运行源程序,模拟内存的分配与回收操作,并记录实验结果。

相关文档
最新文档