实验五 动态分区存储管理

合集下载

动态分区管理实验报告

动态分区管理实验报告

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

设计思路:在空闲分区链中找最适合的空闲块,使内存碎片尽量的减少!根据最佳适应算法原理,在内存分配函数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,按高址到低址的顺序。

动态异长分区的存储分配与回收算法

动态异长分区的存储分配与回收算法

实验5 动态异长分区的存储分配与回收算法5.1 实验目的理解存储管理的功能,掌握动态异长分区的存储分配与回收算法。

存储器是计算机系统中的关键资源,存储管理一直是操作系统的最主要功能之一。

存储管理既包括内存资源管理,也包括用于实现分级存储体系的外存资源的管理。

通常,内存与外存可采用相同或相似的管理技术,如内存采用段式存储管理,则外存也采用段式存储管理。

存储管理需要完成如下功能:存储分配、存储共享、存储保护、存储扩充、地址映射。

当一个作业进入内存时,由操作系统将其变为进程,并为进程分配存储空间。

进程运行结束时, 由操作系统将其所占用的存储空间收回。

不同的操作系统对内存空间的划分与分配方法是不同的,通常分为两类:静态等长分区的分配和动态异长分区的分配。

静态等长分区常用于页式存储管理方式与段页式存储管理方式,存储空间被静态地划分为若干个长度相等的区域,每个区域被称作一个页面。

动态异长分区常用于界地址存储管理方式与段式存储管理方式,存储空间被动态地划分为若干个长度不等的区域。

5.2 实验要求本实验要求模拟动态异长分区的分配算法、回收算法和碎片整理算法。

5.3 实验步骤5.3.1 数据结构分析为了实现存储资源的分配和回收,操作系统需Array要记录内存资源使用情况,即哪些区域尚未分配,哪些区域已经分配以及分配给哪些进程等。

为此一般需要两个表,一个为分配表, 另外一个为空闲区域表。

前者记录已经分配的区域, 后者记录着所有当前未被进程占用的空闲区域, 如图5-1所示。

图5-1 空闲区域表显然, 没有记录于表中的区域即为已被进程所占用的非空闲区域,在实际的操作系统中,这些区域登记在进程的PCB中。

而PCB中除了关于内存资源的信息外,还有其它大量信息。

由于本实验是对存储管理算法的模拟,所以用一个线程来代表一个进程,用线程驻留区域表来描述线程占用的内存空间,如图5-2所示。

图5-2 线程驻留区表同时,需要一张表来记录各个线程对内存的请求信息,如图5-3所示。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法存储管理是计算机系统中的重要组成部分,它负责管理和分配计算机中的物理内存资源。

在计算机系统中,通过动态分区分配和回收算法来实现对这些资源的有效利用。

本文将介绍动态分区分配和回收算法的原理、主要算法以及优缺点。

动态分区分配是一种灵活、动态的内存分配方式,它根据进程的需求动态地分配内存空间。

动态分区分配算法有多种,其中最常用的有首次适应算法、最佳适应算法和最坏适应算法。

首次适应算法(First Fit)是最常用的分配算法之一、它从低地址开始寻找第一个满足要求的空闲分区来分配进程。

这种算法的优点是简单、高效,但是可能会产生大量的碎片空间,降低内存的利用率。

最佳适应算法(Best Fit)是在所有空闲分区中找到一个大小最适合进程的分区来分配。

它的主要思想是选择一个更接近进程大小的空闲分区,以减少碎片空间的产生。

然而,这种算法的缺点是需要遍历整个空闲分区链表,因此效率相对较低。

最坏适应算法(Worst Fit)与最佳适应算法相反,它选择一个大小最大的空闲分区来分配进程。

这种算法的好处是可以尽可能地保留大块的碎片空间,以便后续分配使用。

但是,它也会导致更多的碎片空间浪费。

动态分区的回收算法是用于回收被释放的内存空间并合并相邻的空闲分区,以尽量减少碎片空间的产生。

常见的回收算法有合并相邻空闲分区算法和快速回收算法。

合并相邻空闲分区算法会在每次有分区被回收时,检查是否有相邻的空闲分区可以合并。

如果有,就将它们合并为一个大的空闲分区。

这样可以最大程度地减少碎片空间,提高内存的利用效率。

快速回收算法是一种将被释放的分区插入到一个空闲分区链表的头部,而不是按照地址顺序进行插入的算法。

这样可以减少对整个空闲分区链表的遍历时间,提高回收的效率。

总结起来,动态分区分配和回收算法在存储管理中起着重要的作用。

首次适应算法、最佳适应算法和最坏适应算法是常用的动态分区分配算法,它们各自有着不同的优缺点。

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

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

动态分区分配存储管理系统一、设计目的与内容用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法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. 掌握常用的页面置换算法。

实验内容:一、选择: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)。

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

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

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

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

首先,让我们定义一个内存大小为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字节的空闲分区。

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告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表示未配}; //空闲分区表第二,在设计的表格上进行内存分配●首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。

存储器管理——动态分区的分配与回收

存储器管理——动态分区的分配与回收

计算机与信息工程系实验报告
班级计算机
1001
姓名李双贺时间2011.11.09 地点A504
实验名称存储器管理——动态分区的分配与回收
实验目的
目的是在学习操作系统理论知识的基础上,对操作系统整体的一个模拟。

研究计算机操作系统的基本原理和算法,掌握操作系统的存储器管理的首次适应算法、循环首次适应算法、最佳适应算法的基本原理和算法。

提高运用操作系统知识和解决实际问题的能力;并且锻炼自己的编程能力、创新能力以及开发软件的能力。

使学生掌握基本的原理和方法,最后达到对完整系统的理解。

实验内容
内存调度策略可采用首次适应算法、循环首次适应算法和最佳适应法等,并对各种算法进行性能比较。

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

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

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

实验结果。

存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法存储管理是操作系统中非常重要的一部分,它负责对计算机系统的内存进行有效的分配和回收。

动态分区分配及回收算法是其中的一种方法,本文将详细介绍该算法的原理和实现。

动态分区分配及回收算法是一种将内存空间划分为若干个动态分区的算法。

当新的作业请求空间时,系统会根据作业的大小来分配一个合适大小的分区,使得作业可以存储在其中。

当作业执行完毕后,该分区又可以被回收,用于存储新的作业。

动态分区分配及回收算法包括以下几个步骤:1.初始分配:当系统启动时,将整个内存空间划分为一个初始分区,该分区可以容纳整个作业。

这个分区是一个连续的内存块,其大小与初始内存大小相同。

2.漏洞表管理:系统会维护一个漏洞表,用于记录所有的可用分区的大小和位置。

当一个分区被占用时,会从漏洞表中删除该分区,并将剩余的空间标记为可用。

3.分区分配:当一个作业请求空间时,系统会根据作业的大小,在漏洞表中查找一个合适大小的分区。

通常有以下几种分配策略:- 首次适应(First Fit): 从漏洞表中找到第一个满足作业大小的分区。

这种策略简单快速,但可能会导致内存碎片的产生。

- 最佳适应(Best Fit): 从漏洞表中找到最小的满足作业大小的分区。

这种策略可以尽量减少内存碎片,但是分配速度相对较慢。

- 最差适应(Worst Fit): 从漏洞表中找到最大的满足作业大小的分区。

这种策略可以尽量减少内存碎片,但是分配速度相对较慢。

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");

存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法⼀、实验⽬的分区管理是应⽤较⼴泛的⼀种存储管理技术。

本实验要求⽤⼀种结构化⾼级语⾔构造分区描述器,编制动态分区匹配算法和回收算法模拟程序,并讨论不同算法的特点。

⼆、实验内容1.编写:First Fit Algorithm2.编写:Best Fit Algorithm3.编写 :空闲区回收算法三,提⽰和说明(⼀)主程序1、定义分区描述器node,包括 3个元素:(1)adr——分区⾸地址(2)size——分区⼤⼩(3)next——指向下⼀个分区的指针2、定义 3个指向node结构的指针变量:(1)head1——空闲区队列⾸指针(2)back1——指向释放区node结构的指针(3)assign——指向申请的内存分区node结构的指针3、定义 1个整形变量:free——⽤户申请存储区的⼤⼩(由⽤户键⼊)(⼆)过程1、定义check过程,⽤于检查指定的释放块(由⽤户键⼊)的合法性2、定义assignment1过程,实现First Fit Algorithm3、定义assignment2过程,实现Best Fit Algorithm4、定义acceptment1过程,实现First Fit Algorithm的回收算法5、定义acceptment2过程,实现Best Fit Algorithm的回收算法6、定义print过程,打印空闲区队列(三)执⾏程序⾸先申请⼀整块空闲区,其⾸址为0,⼤⼩为32767;然后,提⽰⽤户使⽤哪种分配算法,再提⽰是分配还是回收;分配时要求输⼊申请区的⼤⼩,回收时要求输⼊释放区的⾸址和⼤⼩。

(四)输出要求每执⾏⼀次,输出⼀次空闲区队列情况,内容包括:编号⾸址终址⼤⼩三、实验过程1.准备A.查阅相关资料;B.初步编写程序;C.准备测试数据;2、主要流程和源代码#include<iostream>#include<stdlib.h>using namespace std;#define Free 0 //空闲状态#define Busy 1 //已⽤状态#define OK 1 //完成#define ERROR 0 //出错#define MAX_length 32767 //最⼤内存空间为32767KB typedef int Status;int n = 0;typedef struct freearea//定义⼀个空闲区说明表结构{int ID; //分区号long size; //分区⼤⼩long address; //分区地址int state; //状态}ElemType;//线性表的双向链表存储结构typedef struct DuLNode //double linked list{ElemType data;struct DuLNode *prior; //前趋指针struct DuLNode *next; //后继指针}DuLNode, *DuLinkList;DuLinkList block_first; //头结点DuLinkList block_last; //尾结点Status alloc(int);//内存分配Status free(int); //内存回收Status First_fit(int, int);//⾸次适应算法Status Best_fit(int, int); //最佳适应算法void show();//查看分配Status Initblock();//开创空间表Status Initblock()//开创带头结点的内存空间链表{block_first = (DuLinkList)malloc(sizeof(DuLNode)); block_last = (DuLinkList)malloc(sizeof(DuLNode)); block_first->prior = NULL;block_first->next = block_last;block_last->prior = block_first;block_last->next = NULL;block_last->data.address = 0;block_last->data.size = MAX_length;block_last->data.ID = 0;block_last->data.state = Free;return OK;}//分配主存Status alloc(int ch){int ID, request;cout << "请输⼊作业(分区号):";cin >> ID;cout << "请输⼊需要分配的主存⼤⼩(单位:KB):";cin >> request;if (request<0 || request == 0){cout << "分配⼤⼩不合适,请重试!" << endl;return ERROR;}if (ch == 2) //选择最佳适应算法{if (Best_fit(ID, request) == OK) cout << "分配成功!" << endl; else cout << "内存不⾜,分配失败!" << endl;return OK;}else //默认⾸次适应算法{if (First_fit(ID, request) == OK) cout << "分配成功!" << endl; else cout << "内存不⾜,分配失败!" << endl;return OK;}}//⾸次适应算法Status First_fit(int ID, int request)//传⼊作业名及申请量{//为申请作业开辟新空间且初始化DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode)); temp->data.ID = ID;temp->data.size = request;DuLNode *p = block_first->next;while (p){if (p->data.state == Free && p->data.size == request) {//有⼤⼩恰好合适的空闲块p->data.state = Busy;p->data.ID = ID;return OK;break;}if (p->data.state == Free && p->data.size>request){//有空闲块能满⾜需求且有剩余"temp->prior = p->prior;temp->next = p;temp->data.address = p->data.address;p->prior->next = temp;p->prior = temp;p->data.address = temp->data.address + temp->data.size; p->data.size -= request;return OK;break;}p = p->next;}return ERROR;}//最佳适应算法Status Best_fit(int ID, int request){int ch; //记录最⼩剩余空间DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode)); temp->data.ID = ID;temp->data.size = request;temp->data.state = Busy;DuLNode *p = block_first->next;DuLNode *q = NULL; //记录最佳插⼊位置while (p) //初始化最⼩空间和最佳位置{(p->data.size>request || p->data.size == request)){q = p;ch = p->data.size - request;break;}p = p->next;}while (p){if (p->data.state == Free && p->data.size == request) {//空闲块⼤⼩恰好合适p->data.ID = ID;p->data.state = Busy;return OK;break;}if (p->data.state == Free && p->data.size>request) {//空闲块⼤于分配需求if (p->data.size - request<ch)//剩余空间⽐初值还⼩{ch = p->data.size - request;//更新剩余最⼩值q = p;//更新最佳位置指向}}p = p->next;}if (q == NULL) return ERROR;//没有找到空闲块else{//找到了最佳位置并实现分配temp->prior = q->prior;temp->next = q;temp->data.address = q->data.address;q->prior->next = temp;q->prior = temp;q->data.address += request;q->data.size = ch;return OK;}}//主存回收Status free(int ID){DuLNode *p = block_first;while (p){if (p->data.ID == ID){p->data.state = Free;p->data.ID = Free;if (p->prior->data.state == Free)//与前⾯的空闲块相连{p->prior->data.size += p->data.size;p->prior->next = p->next;p->next->prior = p->prior;}if (p->next->data.state == Free)//与后⾯的空闲块相连{p->data.size += p->next->data.size;p->next->next->prior = p;p->next = p->next->next;}break;}p = p->next;}return OK;}// 显⽰主存分配情况void show(){cout << "***********-----------------************" << endl; cout << "**** 主存分配情况 ****" << endl; cout << "***********-----------------************" << endl; DuLNode *p = block_first->next;while (p){cout << "分区号:";if (p->data.ID == Free) cout << "Free" << endl;else cout << p->data.ID << endl;cout << "起始地址:" << p->data.address << endl;cout << "分区⼤⼩:" << p->data.size << " KB" << endl; cout << "状态:";if (p->data.state == Free) cout << "空闲" << endl;else cout << "已分配!" << endl;cout << "-----------------------" << endl;p = p->next;}}//主函数int main(){int ch, d = 0;//算法选择标记cout << "1.⾸次适应算法 2.最佳适应算法 0.退出" << endl; cout << "请选择分配算法:";cin >> ch;if (ch == 0 || ch == 1 || ch == 2) d++;while (d == 0){cout << "请选择正确的数字0 ,1 或2" << endl;cin >> ch;if (ch == 0 || ch == 1 || ch == 2) d++;}if (ch == 0) exit(0);if (n == 0) Initblock(); //开创空间表int choice; //操作选择标记while (1){cout << "********************************************" << endl; cout << "** 1: 分配内存 2: 回收内存 **" << endl; cout << "** 3: 查看分配 0: 返回 **" << endl; cout << "********************************************" << endl; cout << "请输⼊您的操作:";cin >> choice;if (choice == 1)alloc(ch); // 分配内存n++;}else if (choice == 2) // 内存回收{int ID;cout << "请输⼊您要释放的分区号:"; cin >> ID;free(ID);n++;}else if (choice == 3){show();//显⽰主存n++;}else if (choice == 0){main(); //退出n++;}else //输⼊操作有误{cout << "输⼊有误,请重试!" << endl; continue;}}}四、实验结果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<<"++++++++++++++++++++++++++++++++++++++ cout<<"+++++++ 空闲区 +++++++\n";cout<<"+++++++++++++++++++++++++++++++++++++++ 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<<"++++++++++++++++++++++++++++++++++++++ cout<<"+++++++ 已分配区 ++++++\n";cout<<"+++++++++++++++++++++++++++++++++++++++ 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. 运行源程序,模拟内存的分配与回收操作,并记录实验结果。

相关文档
最新文档