试验四存储管理可变分区

合集下载

操作系统实验-可变分区存储管理

操作系统实验-可变分区存储管理

作业一实验一 :可变分区存储管理(一) 实验题目编写一个C 程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),模拟可变分区内存管理,实现对该内存区的分配和释放管理。

(二) 实验目的1.加深对可变分区的存储管理的理解;2.提高用C 语言编制大型系统程序的能力,特别是掌握C 语言编程的难点:指针和指针作为函数参数;3.掌握用指针实现链表和在链表上的基本操作。

(三)程序代码 #include<malloc.h> #include<stdio.h> #include<string.h>#define new(type) (type *)malloc(sizeof(type))typedef struct _map {unsigned int size; char *address; struct _map *next; struct _map *prev;(a)(b)(c)(d)图2-9释放区与前后空闲区相邻的情况} map;typedef map *pmap;typedef struct _mem{unsigned int totalSize;char* space;pmap head;pmap cMap;} mem;typedef mem *pmem;pmem createMem(unsigned int to_size) //创建内存区域{pmem newMem=new(mem);pmap newHead=new(map);newMem->totalSize=to_size;newHead->size=to_size;newHead->address=newMem->space;newHead->next=newHead;newHead->prev=newHead;newMem->head=newHead;newMem->cMap=newHead;return newMem;}void freeMem(pmem m){pmap map,cMap;pmap head=m->head;free(map->address);for(map=head;map->next!=head;){cMap=map;map=cMap->next;free(cMap);}free(m);}char* lmalloc(pmem cMem,unsigned int size) //分配函数{if(size>1000){printf("内存容量超出范围!\n"); //当需要分配的内存空间已经大于实际空间时出错}else{pmap p=cMem->cMap;char* rAddr;if(size==0)return NULL;while(p->size<size){if(p->next==cMem->cMap)return NULL;p=p->next;}rAddr=p->address;p->size-=size;p->address+=size;if(p->size==0){p->prev->next=p->next;p->next->prev=p->prev;cMem->cMap=p->next;if(cMem->head==p)cMem->head=p->next;if(p->next!=cMem->head)free(p);}else{cMem->cMap=p;}return rAddr;}}void lfree(pmem m,unsigned int size,char* addr) //释放函数{pmap nextMap,prevMap,newMap;if(addr<m->space || addr>=m->space+m->totalSize){fprintf(stderr,"地址越界\n"); //释放空间时,大小输入出错return;}nextMap=m->head;while(nextMap->address<addr){nextMap=nextMap->next;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->size+=nextMap->size;prevMap->next=nextMap->next;prevMap->next->prev=prevMap;if(nextMap==m->cMap){m->cMap=prevMap;}free(nextMap);nextMap=NULL;}}else{if(addr+size==nextMap->address) //第三种情况{nextMap->address-=size;nextMap->size+=size;}else //第四种情况{newMap=new(map);newMap->address=addr;newMap->size=size;prevMap->next=newMap;newMap->prev=prevMap;newMap->next=nextMap;nextMap->prev=newMap;if(nextMap==m->head)m->head=newMap;}}}void printMem(pmem m) //打印函数{pmap map=m->head;printf("\空闲内存空间:\n\-----------------------\n\大小起始地址\n");do{if(map==m->cMap)printf("-> ");elseprintf(" ");printf("%10u %10u\n",map->size,map->address);map=map->next;}while(map!=m->head);printf("-----------------------\n");}void main() //主函数{printf("--------------------------------------------------------\n");printf("请选择操作:分配内存(m) or 释放内存(f) or 打印内存表(p)\n");printf("--------------------------------------------------------\n");typedef enum{cmdMalloc,cmdFree,cmdPrint,cmdHelp,cmdQuit,cmdInvalid} cmdType; pmem m=createMem(1000);char cmd[20];char *addr;unsigned int size;cmdType type;while(1){scanf("%s",cmd);if(cmd[1]=='\0'){switch(cmd[0]){case 'm':case 'M':type=cmdMalloc;break;case 'f':case 'F':type=cmdFree;break;case 'p':case 'P':type=cmdPrint;break;}}else{if(!strcmp(cmd,"malloc"))type=cmdMalloc;else if(!strcmp(cmd,"free"))type=cmdFree;else if(!strcmp(cmd,"print"))type=cmdPrint;}switch(type){case cmdMalloc:scanf("%u",&size);lmalloc(m,size);printMem(m);break;case cmdFree:scanf("%u %u",&size,&addr);lfree(m,size,addr);printMem(m);break;case cmdPrint:printMem(m);break;return;}}}(四)程序结果。

存储管理实验报告总结(3篇)

存储管理实验报告总结(3篇)

第1篇一、实验背景存储管理是操作系统的重要组成部分,负责对计算机的存储资源进行合理分配、有效利用和保护。

为了加深对存储管理原理和方法的理解,我们进行了存储管理实验,通过编写和调试模拟程序,对存储管理技术进行了深入学习和实践。

二、实验目的1. 理解存储管理的概念、原理和方法。

2. 掌握不同存储管理技术的实现过程。

3. 分析存储管理技术的优缺点,为实际应用提供参考。

三、实验内容1. 可变分区存储管理实验实验目的:了解可变分区存储管理的原理和实现方法。

实验内容:(1)编写程序实现内存空间的分配和回收。

(2)采用最优适应算法、首次适应算法、下次适应算法等,模拟内存分配过程。

(3)分析不同分配算法的性能。

实验结果:通过实验,我们了解了可变分区存储管理的原理和实现方法,并分析了不同分配算法的性能。

2. 分页存储管理实验实验目的:掌握分页存储管理的基本概念和实现方法。

实验内容:(1)编写程序实现内存空间的分配和回收。

(2)采用页式存储管理技术,模拟内存分配过程。

(3)分析页面置换算法的性能,如LRU、FIFO等。

实验结果:通过实验,我们掌握了分页存储管理的基本概念和实现方法,并分析了页面置换算法的性能。

3. 虚拟页式存储管理实验实验目的:了解虚拟页式存储管理的原理和实现方法。

实验内容:(1)编写程序实现虚拟内存的分配和回收。

(2)采用工作集算法、抖动预防等技术,模拟虚拟内存的访问和页面置换过程。

(3)分析虚拟页式存储管理技术的优缺点。

实验结果:通过实验,我们了解了虚拟页式存储管理的原理和实现方法,并分析了其优缺点。

四、实验总结1. 通过本次实验,我们对存储管理技术有了更深入的理解,掌握了不同存储管理技术的实现方法。

2. 实验过程中,我们学会了编写模拟程序,通过程序模拟存储管理过程,验证了存储管理技术的性能。

3. 实验结果分析表明,不同存储管理技术具有不同的优缺点,在实际应用中应根据具体需求选择合适的存储管理技术。

可变分区存储管理实验报告程序设计思路和感悟参考模板

可变分区存储管理实验报告程序设计思路和感悟参考模板

实验题目:可变分区存储管理一、实验目的可变分区存储管理方式是操作系统中存储管理的重要方式,其主要思想是用户作业进行连续存储,每次按照用户的请求,如果内存中有能满足用户作业大小的空闲区,就采用不同的算法分配给用户,否则,不分配,可变分区容易产生外零头。

分区分配算法包括最佳适应算法、最坏适应算法、首次适应算法等。

通过本实验可加深学生对存储器管理方式的把握以及分配算法的理解,并提高程序设计的能力。

二、实验环境个人PC机WindowsXP操作系统I5-2400CPU 3.10Ghz 2GB内存C-Free C语言程序设计软件三、实验的重点和难点可变分区的的收回四、实验内容利用C语言或C++语言或Java语言实现可变分区存储管理,具体要求如下:1. 以一个一维数组模拟内存,数组类型为整型,共计1000个元素;2. 用一个单链表表示可变分区空闲表,链表每个结点表示一个空闲区,每个结点信息包括起始地址、大小。

3. 分区分配算法采用最佳适应算法、首次适应算法,并将算法用函数实现。

4. 自己假设几个作业,包括作业的名称、大小,进入系统的顺序。

5. 初始内存中没有任何作业,随着用户输入的每一个作业的到来,动态为其分配内存。

6. 使用的算法用户要能够随时更换。

五、实验结果或实验代码(1) 可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数可以调整。

当要装入一个作业时,根据作业需要的内存量,查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若没有,则作业等待。

随着作业的装入、完成,内存空间被分割成许多大大小小的分区。

有的分区被作业占用,有的分区空闲。

例如,某时刻内存空间占用情况如图1所示。

为了说明那些分区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,如表1所示。

表1 空闲区说明表图1 内存空间占用情况62241其中,起始地址指出个空闲区的内存起始地址,长度指出空闲区的大小。

可变分区实验

可变分区实验

可变分区实验一、实验题目:编写一个C程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),用循环首次适应法addr = (char *) lmalloc (unsigned size) 和lfree (unsigned size , char * addr)模拟UNIX可变分区内存管理,实现对该内存区的分配和释放管理。

二、实验目的:1.加深对可变分区的存储管理的理解;2.提高用C语言编制大型系统程序的能力,特别是掌握C语言编程的难点:指针和指针作为函数参数;3.掌握用指针实现链表和在链表上的基本操作。

三、实验分析:本实验采用循环首次适应法的方法来模拟UNIX的可变分区内存管理。

即对于系统中内存空闲区域表采用双向链表的形式存储。

当需要申请分配内存时,指向该区域表的指针搜索该表,在指针行走完一圈以前,一旦找到可以分配的空闲内存块即采用该空闲区域进行分配,并返回指向实际空闲区的指针。

此外,指向该循环链表的指针应当在没有操作的时候保持位置,完成操作后指向操作过的那个表项。

而释放内存也是基于基本相同的做法,但在释放后应当注意到相邻空闲区域的合并。

除了分配和释放这两个主要模块以外,系统还应当具备差错处理、初始化、释放退出等合理的功能。

四、概要设计:本试验程序共10个模块,分别如下:1. 主程序模块main( )2. 初始化系统模块x_Initialize( )3. 命令处理模块x_Order( )4. 错误命令处理模块x_ErrorOrder( )5. 分配内存模块x_ApplyMem( )6. 分配内存失败处理模块x_ErrorApply( )7. 释放内存模块x_FreeMem( )8. 释放内存失败处理模块x_ErrorFree( )9. 打印空闲分区情况表模块x_PrintT able( )10. 结束退出处理模块x_EndProgram( )概要设计结构图(Structure Chart)如下:程序基本流程图:1.内存空闲区域表单元(全局变量):struct map{/*unit in the free space record table*/ unsigned long x_MemSize;char *x_MemAddr;struct map *x_TablePrev,*x_TableNext;};2.内存空闲区域表项指针(全局变量):struct map *x_TableStart;3.申请分配的内存总量(全局变量):unsigned long x_WholeMemSize=1024;4.申请分配的内存块的首地址指针(全局变量)char *x_Start;5.模拟申请分配或释放的内存量unsigned long x_MemAmount;6.返回的模拟内存分配的指针char *x_Return;7.要求释放的内存的起始相对地址unsigned long x_FreeAddr六、主要模块详细设计:1.初始化模块:x_Initialize( )输入值:无返回值:无操作变量:x_TableStart调用模块:打印表单模块x_PrintT able( )详细设计:(伪代码)申请内存空闲区域表单元;建立内存空闲区域表并初始化;输出提示信息;打印该表单;2.命令处理模块x_Order( )输入值:无返回值:无操作变量:x_MemAmount,x_FreeAddr调用模块:x_ApplyMem( ),x_FreeMem( ),x_ErrorOrder(),x_PrintTable( ),x_EndProgram( )详细设计:for(;;){给出提示信息,接受用户命令;匹配用户命令;if(是内存分配命令){for(;读入字符是数字;)将字符格式的内存区域量转变为整数形式的内存区域量;if(接下来的字符不是结束符或者没有输入内存区域量)x_ErrorOrder( );else /*输入命令符合格式*/x_ApplyMem( x_MemAmount );}else if(是释放内存命令){for(;读入首批字符是数字;)将字符格式的内存起始相对地址转变为整形;if(接下来的字符不是空格)x_ErrorOrder( );for(;读入字符是数字;)将字符格式的内存量转变为整形;if(接下来的字符不是结束符或没有输入内存量)x_ErrorOrder( );else /*输入命令符合格式*/x_FreeMem( x_FreeAddr , x_MemAmount );}else if(是结束程序的命令){x_EndProgram( );跳出;}else /*输入命令不合格式*/{x_ErrorOrder( );}打印表单;3.分配内存模块x_ApplyMem( )输入值:x_MemAmount返回值:x_Return操作变量:x_TableStart,x_Return调用模块:x_ErrorApply( )详细设计:if(空闲区域内存表不空){do{if(遍历链表指针指向的单元的空闲内存量大于申请量){为x_Return赋值;修改该链表单元的成员值;if(剩余的空闲内存量为0){if(该表只有一个单元了)删除该单元,链表起始指针置空;break;else删除该单元,妥善处理链表;}提示信息给出,返回指针;}移动遍历指针;}while(遍历指针与起始指针不相等);}x_ErrorApply( );返回空指针;4.释放内存模块x_FreeMem( )输入值:x_MemAmount , x_FreeAddr返回值:无操作变量:x_TableStart调用模块:x_ErrorFree( )详细设计:(伪代码)初始化遍历指针等辅助变量;if(要求释放的内存起始或终止地址越界)记录错误;else{if(原空闲内存区域表为空){申请单元表项;初始化该表项并建立该表;记录操作成功;}else{do{if(要求释放的内存起始地址已经存在于表中了)记录错误;移动遍历指针;}while(遍历指针等于起始指针);if(没有错误记录){do{if(前项地址小于后项地址){/*指针区域处于该表的折返处*/if(要求释放的起始指针在两块之前或后,未临界){申请新表项;初始化并完善链表;记录成功;跳出;}else if(要求释放的内存临界于前项){修改前项的参数;移动链表起始指针;记录成功;跳出;}else if(要求释放的内存临界于后项){修改后项的参数;移动链表起始指针;记录成功;跳出;}}else if(前后项地址相同){/*只有一项*/同样按以上三种情况处理;else{if(释放区域在两项之中,且临界){合并、修改前后项,并删除前项;移动链表起始指针;记录成功;跳出;}else if(释放区域与前项临界){修改前项;移动链表起始指针;记录成功;跳出;}else if(释放区域与后项临界){修改后项;移动链表起始指针;记录成功;跳出;}else if(释放区域在前后项之中,不临界){申请新表项;初始化并完善链表;记录成功;跳出;}}}while(起始指针不等于遍历指针)}}}if(没有记录成功){x_ErrorApply( );}七、原程序代码请参见F005-093-LiuXin.c ,其中包含有测试数据及测试结果八、测试方案及结果在本实验中,我们采用白盒法的方法,即保证每一条支路都要至少走一遍。

实验4:可变分区存储管理

实验4:可变分区存储管理

沈阳工程学院
学生实验报告
(课程名称:操作系统)实验题目:可变分区存储管理
班级学号姓名
地点f612 指导教师
实验日期:
{
case 0:printf("感谢您的使用!再见!\n");exit(0);
case 1:view();break;
case 2:earliest();break;
case 3:excellent();break;
case 4:worst();break;
}
system("cls");
}
}
①建立文件以adc为名字的文件输入如图1所示

1 建立文件adc
②建立3个空闲分区起始地址和行实现如图2所示
图2 建立起始地址③显示空闲表和分配表实现如图3所示
图3 显示空闲表和分配表
④执行首次算法后,建立的空闲表长度分别为3 8 10,申请一个名为a长度为5的作业故首次适应算法从第二个空闲表首地址为3开始,运行实现如图4所示
图4 首次适应算法
⑤最佳适应算法,执行首次算法后,建立的空闲表长度分别为3 8 10,申请一个名为a长度为9的作业故首次适应算法从第二个空闲表首地址为11开始,运行实现如图5所示
图5 最佳适应算法
⑥最坏适应算法,执行首次算法后,建立的空闲表长度分别为3 8 10,申请一个名为a长度为3的作业故首次适应算法从第二个空闲表首地址为11开始,运行实现如图6所示
图6 最坏适应算法⑦生成文件abc如图7所示
图7 生成a文件。

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

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

实验四实验四可变分区存储管理方式的内存分配和回收一.实验目的通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。

二.实验属性设计三.实验内容1.确定内存空间分配表;2.采用最优适应算法完成内存空间的分配和回收;3.编写主函数对所做工作进行测试。

四.实验背景材料实现可变分区的分配和回收,主要考虑的问题有三个:第一,设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计内存分配算法;第三,在设计的数据表格基础上设计内存回收算法。

首先,考虑第一个问题,设计记录内存使用情况的数据表格,用来记录空间区和作业占用的区域。

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

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

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

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

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

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

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

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

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

由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。

它们的长度必须是系统可能的最大项数。

“已分分区表”的结构定义#define n 10 //假定系统允许的最大作业数量为nstruct{ float address; //已分分区起始地址float length; //已分分区长度、单位为字节int flag; //已分分区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名}used_table[n]; //已分分区表“空闲区表”的结构定义#define m 10 //假定系统允许的空闲区最大为mstruct{ float address; //空闲区起始地址float length; //空闲区长度、单位为字节int flag; //空闲区表登记栏标志,“0”表示空栏目,“1”表示未分配}used_table[n]; //空闲区表第二,在设计的数据表格基础上设计内存分配。

操作系统 可变分区存储管理

操作系统 可变分区存储管理

实验二、可变分区存储管理一、实验目的熟悉主存的分配与回收。

理解在不同的存储管理方式下,如何实现主存空间的分配与回收。

掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。

所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。

所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。

可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。

随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。

实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。

同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。

同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。

三、实验主要仪器设备和材料实验环境硬件环境:IBM-PC或兼容机软件环境:VC++ 6.0四、实验原理及设计分析某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。

(作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放60KB 、作业4 申请200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB)当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。

试验四:存储管理----可变分区

试验四:存储管理----可变分区

存储管理实验----可变分区管理实验目的:通过分区存储管理模拟算法,了解可变分区的内存分配和回收过程,熟悉内存分配之最先、最佳、最差适应算法。

实验内容:1.阅读参考程序,写出该程序的内存分配算法是哪种?2.完善内存回收算法。

3.设计最先内存分配算法,分配从小地址开始;参考程序#include <stdio.h>#include <stdlib.h>#define n 10 /*假定系统允许的最大作业数为n,假定模拟实验中n值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/#define minisize 100 /*空闲分区被分配时,如果分配后剩余的空间小于minisize,则将该空闲分区全部分配,若大于minisize,则切割分配,即不留小碎片*/struct{float address; /*已分配分区起始地址*/float length; /*已分配分区长度,单位为字节*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/}used_table[n]; /*已分配区表。

即存放已经分配的分区*/struct{float address; /*空闲区起始地址*/float length; /*空闲区长度,单位为字节*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,可用来登记空闲区,用"1"表示该空闲区未分配*/}free_table[m]; /*空闲区表,即存放空闲分区*//*主存分配函数*/void allocate(char J,float xk) /*给J作业,采用最佳分配算法分配xk大小的空间*/{int i,k;float ad;k=-1;for(i=0;i<m;i++) /*寻找空间大于xk的最小空闲区登记项k*/if(free_table[i].length>=xk && free_table[i].flag==1)if(k==-1||free_table[i].length<free_ta69ble[k].length)k=i;if(k==-1)/*未找到可用空闲区,返回*/{printf("无可用空闲区\n");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<n) /*寻找空表目*/i++;if(i>=n) /*无表目可填写已分配分区*/{printf("无表目填写已分分区,错误\n");/*修正空闲区表*/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;}/*主存分配函数结束*//*主存回收函数*/void reclaim(char 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的作业*/{printf("找不到该作业\n");return;}/*修改已分配表*/used_table[s].flag=0;/*取得归还分区的起始地址S和长度L*/S=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;/*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/while(i<m&&(j==-1||k==-1)){if(free_table[i].flag==1){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)/* 上邻空闲区,下邻空闲区,三项合并*/{。

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

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

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

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

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

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

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

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

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

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

分区存储管理实验指导书

分区存储管理实验指导书

实验六——分区存储管理目录一、概述(一) 可变分区存储管理(二) 实验条件二、实验目的三、实验任务四、实验内容(一) 首次适应分配算法(二) 最佳适应分配算法(三) 最坏适应分配算法(四) 三种算法的比较一、概述(一)可变分区存储管理内存管理的可变分区模式,又称变长分区模式、动态分区分配模式。

这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。

因此系统分区的大小和数目是可变的。

与固定分区的区别就是:动态的划分分区。

克服固定分区管理的“内碎片”问题。

1. 可变分区模式下,刚开始,OS就绪,但任何用户程序未进入内存前整个用户内存区是一大空间。

已占用区和空闲分区并不是绝对的。

2. 必须有表来记录分区的情况。

3. 程序进入内存时的例行工作就是分配空闲区和装入程序,并修改相应的空闲表和已分配区表。

4. 一旦一个内存分区被分配给一个进程,该进程可以被装入该块中执行,装入时需重定位。

(二)实验条件1. Linux 操作系统2. VI 编辑器3. GCC 编译器(三)衡量算法分配性能指标二、实验目的1. 加深对分区存储管理概念的理解2. 掌握首次适应分配算法、最佳适应分配算法、最坏适应分配算法。

3. 了解可变分区存储管理的作用,学会衡量各算法分配性能指标。

三、实验任务根据上课讲解的例子来进行实验--代码中设置默认内存为一整个大的分区(大小为100),所以先分配九个分区(大小不等),然后回收0、2、4、6、8号分区,使其空闲,此时1、3、5、7号分区的状态为“已使用”(隔开空闲分区)。

然后再使用首次适应分配、最佳适应分配、最坏适应分配三种算法进行内存分配。

(提示:由于代码中设置:分区size小于2时,将不再分割内存,所以当内存分配了一个分区后只剩下2时将把这一个大小为2的分区一起分配过去。

)(一)设置九个分区大小并回收个别分区运行1.c的代码,我们需要先将内存分为五个空闲区域,九个空闲分区大小可参考以下数据:(整个空闲区大小为100)15 8 9 13 10 17 12 5 11然后回收0、2、4、6、8号分区,使其空闲,1、3、5、7号分区的状态为“已使用”(隔开空闲分区)。

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

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

沈阳工程学院学生实验报告实验室名称:信息工程系信息安全实验室实验课程名称:操作系统实验项目名称:可变分区存储管理班级:计专本121 姓名:郑永凯学号:2012461127 实验日期:2013 年5 月27日实验台编号:F608指导教师:张楠批阅教师(签字):成绩:#include<stdio.h> #include<stdlib.h> #define NULL 0#define getjcb(type) (type*)malloc(sizeof(type))#define getsub(type) (type*)malloc(sizeof(type))int num,num2; //要调度的作业数和要回收的区域数int m=0; //已分配作业数int flag; //分配成功标志intisup,isdown; //回收区域存在上邻和下邻的标志int is=0;structjcb{char name[10];char state;intntime; //所需时间int size; //所需空间大小intaddr; //所分配分区的首地址structjcb *link;} *ready =NULL, *p,*q,*as=NULL;//作业队列ready,已分配作业队列as typedefstructjcb JCB;struct subarea{ //分区块char name[10];intaddr; //分区首地址int size; //分区大小char state;struct subarea *link;} *sub=NULL,*r,*s,*cur; //空闲分区队列sub,当前分区指针cur typedefstruct subarea SUB;void sort() /* 建立对作业按到达时间进行排列的函数,直接插在队列之尾*/ {JCB *first;if(ready==NULL) ready=p;else{first=ready;while(first->link!=NULL)first=first->link;first->link=p;p->link=NULL;}}void sort3() /*建立对已分配作业队列的排列函数,直接插在队列之尾*/ {JCB *fir;if(as==NULL) as=q;else{fir=as;while(fir->link!=NULL)fir=fir->link;fir->link=q;q->link=NULL;}m++;}void input() /* 建立作业控制块函数*/{int i;printf("\n请输入要调度的总作业数:");scanf("%d",&num);for(i=0;i<num;i++){printf("\n作业号No.%d:\n",i);p=getjcb(JCB);printf("\n输入作业名:");scanf("%s",&p->name);printf("\n输入作业的大小:");scanf("%d",&p->size);printf("\n输入作业所需运行时间:");scanf("%d",&p->ntime);p->state='w';p->link=NULL;sort(); /* 调用sort函数*/}printf("\n 按任一键继续......\n");getch();}void input2() /*建立要回收区域的函数*/{JCB *k;int has;q=getjcb(JCB);printf("\n输入区域名(作业名):");scanf("%s",&q->name);p=as;while(p!=NULL){if(strcmp(p->name,q->name)==0) /*在已分配作业队列中寻找*/{q->addr=p->addr;q->size=p->size;has=1; /*输入作业名存在标志位*/if(p==as) as=p->link; /*在已分配作业队列中删除该作业*/ else{k=as;while(k->link!=p) k=k->link;k->link=k->link->link; /*删除*/}printf("输出该作业首地址:%d\n",q->addr);printf("输出该作业大小:%d\n\n",q->size);q->link=NULL;break;}else{p=p->link; has=0;} /*输入作业名不存在标志*/}if(has==0){printf("\n输入作业名错误!请重新输入!\n");input2();}}void print(){printf("\n\n\n\n");printf("\t\t**************************************\n");printf("\t\t\t三.存储管理实验演示\n");printf("\t\t**************************************\n\n\n");printf("\t\t\t\t123456\n");printf("\t\t\t\t信自学院\n");printf("\t\t\t\t计专本121\n");printf("\t\t\t\t2012461119\n");printf("\t\t\t\t2013年5月\n");printf("\n\n\n");printf("\t\t\t按任意键进入演示");getch();system("cls");}void init_sub() /*初始化空闲分区表*/{r=getsub(SUB);strcpy(r->name,"0"); r->addr=5; r->size=10; r->state='F';sub=r;s=getsub(SUB);strcpy(s->name,"1"); s->addr=20; s->size=120; s->state='F';sub->link=s;r=s;s=getsub(SUB);strcpy(s->name,"2"); s->addr=160; s->size=40; s->state='F';r->link=s;r=s;s=getsub(SUB);strcpy(s->name,"3"); s->addr=220; s->size=10; s->state='F';r->link=s;r=s;s=getsub(SUB);strcpy(s->name,"4"); s->addr=250; s->size=20; s->state='F';r->link=s;r=s;s=getsub(SUB);strcpy(s->name,"5"); s->addr=300; s->size=80; s->state='F';r->link=s;s->link=0;}//--------------------------------------------------------------------------void disp() /*空闲分区表的显示函数*/{printf("\n\n");printf("\t\t 分区首地址长度状态\n");r=sub;while(r!=NULL){printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",r->name,r->addr,r->size,r->state);r=r->link;}printf("\n");}void disp2() /*显示已分配内存的作业表函数*/{printf("\n\n");printf("\t\t 作业名首地址长度状态\n");p=as;while(p!=NULL){printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",p->name,p->addr,p->size,p->state);p=p->link;}printf("\n\n");}void assign2(JCB *pr) /*首次适应作业分区*/{SUB *k;r=sub; /*从空闲表头开始寻找*/while(r!=NULL){if(((r->size)>(pr->size))&&(r->state=='F')) /*有空闲分区大于作业大小的情况*/ {pr->addr=r->addr;r->size-=pr->size;r->addr+=pr->size;flag=1; /*分配成功标志位置1*/q=pr;q->state='r';sort3(); /*插入已分配作业队列*/printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);break;}else if(((r->size)==(pr->size))&&(r->state=='F')) /*有空闲分区等于作业大小的情况*/ {pr->addr=r->addr;flag=1; /*分配成功标志位置1*/q=pr;sort3(); /*插入已分配作业队列*/s=sub; /*空闲分区已完成分配,应删除*/while(s->link!=r) s=s->link;s->link=s->link->link; /*删除空闲分区*/printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);break;}else{r=r->link; flag=0;}}if(flag==0) /*作业过大的情况*/{printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name);is=1;}}void reclaim2(JCB *pr) /*首次适应与循环首次适应区域回收*/{SUB *k;r=sub;while(r!=NULL){if(r->addr==((pr->addr)+(pr->size))) /*回收区域有下邻*/{pr->size+=r->size;s=sub;isdown=1; /*下邻标志位置1*/while(s!=NULL){if(((s->addr)+(s->size))==(pr->addr)) /*有下邻又有上邻*/{s->size+=pr->size;k=sub;while(k->link!=r) k=k->link;k->link=k->link->link;isup=1; /*上邻标志位置1*/break;}else{s=s->link; isup=0;} /*上邻标志位置0*/}if(isup==0) /*有下邻无上邻*/{r->addr=pr->addr;r->size=pr->size;}break;}else{r=r->link; isdown=0;} /*下邻标志位置0*/}if(isdown==0) /*区域无下邻*/{s=sub;while(s!=NULL){if(((s->addr)+(s->size))==(pr->addr)) /*无下邻但有上邻*/{s->size+=pr->size;isup=1; /*上邻标志位置1*/break;}else{ s=s->link; isup=0;} /*上邻标志位置0*/}if(isup==0) /*无下邻且无上邻*/{k=getsub(SUB); /*重新生成一个新的分区结点*/strcpy(k->name,pr->name);k->addr=pr->addr;k->size=pr->size;k->state='n';r=sub;while(r!=NULL){if((r->addr)>(k->addr)) /*按分区首地址排列,回收区域插在合适的位置*/{if(r==sub) /*第一个空闲分区首址大于回收区域的情况*/ { k->link=r; sub->link=k; }else{s=sub;while(s->link!=r) s=s->link;k->link=r;s->link=k;}break;}else r=r->link;}if(r==NULL) /*所有空闲分区的首址都大于回收区域首址的情况*/ {s=sub;while(s->link!=NULL) s=s->link;s->link=k;k->link=NULL;}}}printf("\n区域%s己回收.",pr->name);}menu(){printf("\n\n\n\t\t**************************************\n");printf("\t\t\t存储管理实验演示\n");printf("\t\t**************************************\n\n\n");printf("\t\t\t 1. 显示空闲分区\n");printf("\t\t\t 2. 分配和回收作业\n");printf("\t\t\t 0. 退出\n");printf("\t\t\t请选择你要的操作:");switch(getchar()){case '1':system("cls");disp();getch();system("cls");menu();break;case '2':system("cls");printf("\n首次适应算法");input();printf("\n");while(num!=0){p=ready;ready=p->link;p->link=NULL;assign2(p);num--;}printf("\n显示回收后的空闲分区表和已分配作业表...");getch();printf("\n\t\t 完成分配后的空闲分区表\n"); disp();printf("\n\t\t 已分配作业表\n"); disp2();if(is==0)printf("\n 全部作业已经被分配内存.");else printf("\n 作业没有全部被分配内存.\n");printf("\n\n按任意键进行区域回收.");printf("\n");while(as!=NULL){getch();input2();printf("按任意键继续...");getch();printf("\n");reclaim2(q);printf("\n显示回收后的空闲分区表和已分配作业表...");getch();printf("\n\t\t 回收后的空闲分区表\n"); disp();printf("\n\t\t 已分配作业表\n"); disp2();printf("\n继续回收...(Enter)");}printf("\n所有已分配作业已完成!");printf("\nPress any key to return...");getch();system("cls");menu();break;case '0':system("cls");break;default:system("cls");menu();}}void main() /*主函数*/{init_sub();print();menu();}。

操作系统实验内存分配

操作系统实验内存分配

实验四存储器管理一、实验名称:存储器管理二、实验目的在TC、VB、Delphi、C++Builder等语言与开发环境中,模拟操作系统的内存管理;通过程序运行所显示的内存使用的各项指标,加深对内存管理的理解。

三、实验内容实现主存储器空间的分配和回收。

本实验有两个题,学生可选择其中的一题做实验。

第一题:在固定分区管理方式下实现主存分配和回收。

第二题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。

[提示]:可变分区方式是按作业需要的主存空间大小来分割分区的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。

随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。

为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:起址长度状态第一栏14 K 12 K 未分配第二栏32 K 96 K 未分配空表目空表目其中,起址——指出一个空闲区的主存起始地址。

长度——指出从起始地址开始的一个连续空闲的长度。

状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白(无效),可用来登记新的空闲区(例如,作业撤离后,它所占的区域就成了空闲区,应找一个“空表目”栏登记归还区的起址和长度且修改状态)。

由于分区的个数不定,所以空闲区说明表中应有适量的状态为“空表目”的登记栏目,否则造成表格“溢出”无法登记。

空闲区表的定义为:#define m 10 /*假定系统允许的空闲区表最大为m*/struct{ float address; /*起始地址*/float length; /*长度*/int flag; /*标志,用“0”表示空栏目,用“1”表示未分配*/ }free_table[m]; /*空闲区表*/上述的这张说明表的登记情况是按提示(1)中的例所装入的三个作业占用的主存区域后填写的。

实验、可变分区存储管理系统模拟——最先适应分配算法

实验、可变分区存储管理系统模拟——最先适应分配算法

实验、可变分区存储管理系统模拟——最先适应分配算法1. 实验⽬的可变分区分配是⼀种重要的存储管理思想,⽬前流⾏的操作系统采⽤的分段存储管理的基本思想就源⾃该⽅法。

本实验的⽬的是通过编程来模拟⼀个简单的可变分区分配存储管理系统,利⽤最先适应分配算法实现。

经过实验者亲⾃动⼿编写管理程序,可以进⼀步加深对可变分区分配存储管理⽅案设计思想的理解。

2. 实验原理固定分区分配按操作系统初始化时划定的分区⽅案为作业分配内存,由于各分区的位置和⼤⼩固定,因此作业所需的内存⼤⼩通常⼩于分到的实际内存的⼤⼩,造成存储空间的浪费。

可变分区分配对此作了改进,它总是根据作业的实际需要分配刚好够⽤的连续存储空间,保证分配给作业的存储空间都是有⽤的,避免了零头的产⽣。

(1)可变分区中的数据结构建⽴描述作业的数据结构作业控制块,⾄少应包括:作业名称作业需要执⾏时间作业的内存需求作业调⼊主存时间作业执⾏结束时间作业所在分区的起始地址建⽴描述内存已分配分区的数据结构;建⽴描述内存未分配的空闲分区的数据结构;空闲分区和已分配分区的信息可以使⽤分区表来描述。

系统中所有空闲分区构成分区表,所有已分配分区构成分配分区表。

出于效率的考虑,也可使⽤分区链来记录分区信息。

分区链是⼀种双向链表,链表的每个结点描述⼀个分区的信息。

系统中所有空闲分区构成空闲分区链,所有已分配分区构成分配分区链。

分配和回收分区时,需要在这两个链表中进⾏结点的查找和插⼊、删除与修改操作。

为改进算法的执⾏效率,可以将分区链按特定的顺序排序。

分区链结点的数据结构为:Struct Section {Section *pPre; //前向指针,指向链表的前⼀个结点int nSart; //分区的起始地址int nSize; //分区的尺⼨Section *pSuf; //后向指针,指向链表的后⼀个结点};可变分区分配算法——最先适应分配算法最先适应分配算法要求空闲分区按地址递增的顺序排列,在进⾏内存分配时,从低地址部分向⾼地址部分查找,直到找到⼀个能满⾜要求的空闲分区为⽌。

实验上机02-可变分区存储管理程序模拟的实现

实验上机02-可变分区存储管理程序模拟的实现

实验题目可变分区存储管理的程序模拟一、可变分区存储管理的基本策略1)不预先划分几个固定分区,分区的建立是在作业的处理过程中进行的,各分区的大小由作业的空间需求量决定。

2)采用指针方式将各个空闲分区链接而成的链表,用以记录主存分配现状。

3)分配与回收算法按空闲分区链接方式的不同分类,有最佳、最坏、首次和下次适应四种算法。

二、程序模拟的设计1、基本思想采用事件驱动模型。

事件有:1)申请主存事件,表示一个作业创建时提出的主存资源要求;2)释放主存事件,表示一个作业结束时其占用主存被回收。

2、数据结构设计1)程序使用的常值和工作变量的说明作业表所含表项的最大数量 MaxAmountOfJobTableItems 10处理的作业的最大数量 MaxAmountOfJobs 20主存空间的最大尺寸 MaxSizeOfMemorySpace 1000作业申请主存的最大尺寸 MaxSizeOfMemoryForAsk 500时间单位的最大值 MaxSizeOfTimeUnit 100占用主存时间单位的最大值 MaxSizeOfOccupyTimeUnit 300占用标志 BUSY 1空闲标志 FREE 0申请标志 ASK 1释放标志 RELEASE 0逻辑是标志 TRUE 1逻辑否标志 FALSE 0尾标志 END -1当前时间 CurrentTime作业计数器 CounterOfJobs作业命名序列字符 SerialCharOfJobName2)事件与事件表typedef struct Event_DataType{ 事件数据类型的定义int EventType; 事件的类型申请ASK或释放RELEASEint OccurTime; 事件发生的时间char JobName; 申请主存或被回收主存的作业名int JobId; 进入系统的作业在作业表中相应表项的编号int SizeOfMemoryForAsk; 作业申请占用主存的尺寸int OccupyTimeOfMemoryForAsk; 作业申请占用主存的时间长度int WaitFlag; 该事件是否等待过TRUE或FALSEint AdmitTime; 申请事件的提交时间或释放事件的处理时间struct Event_DataType *Next; 下一事件的指示信息} Event_DataType;设立3个事件表事件表TableOfEvents等待事件表TableOfWaitEvents 用于存放未能及时处理的主存申请事件统计事件表TableOfSumEvents 用于备份事件表3)字单元与主存空间typedef struct Word_DataType{ 主存物理单元数据类型定义int State; 所在分区的状态 FREE或BUSYint Size; 所在分区的大小char JobName; 占用分区的作业名int Next; 相邻分区的指示信息(前相邻或后相邻)} Word_DataType;主存空间是字单元的数组MemorySpace[MaxSizeOfMemory]4)作业表项与作业表typedef struct JobTableItem_DataType{ 作业表项的数据类型定义int State; 表项的状态FREE或BUSYchar JobName; 占用的作业名int MemoryLocation; 作业的主存位置int OccupyTimeOfMemory; 作业占用主存的时间长度int Next; 下一个空闲表项} JobTableItem_DataType;作业表是作业表项的数组TableOfJobs[MaxAmountOfJobTableItems] 5)核心数据结构typedef struct KernalDataStructure_DataType{ 核心数据结构数据类型定义JobTableItem_DataType TableOfJobs[MaxAmountOfJobTableItems];一张作业表int AmountOfFreeItems; 空闲表项的数量int FirstFreeItem; 第一个空闲表项int AmountOfFreeAreas; 空闲分区的数量int FirstFreeArea; 第一个空闲分区int SizeOfFreeMemory; 空闲主存的尺寸} KernalDataStructure_DataType;3、处理流程设计参数说明:形、变参数的区分按参数的逻辑意义认定。

分区式存储管理实验报告

分区式存储管理实验报告

操作系统实验报告(四)分区式存储器管理专业:XXX姓名:XXX班级:XXX学号:XXX指导老师:XXX2013/12/3实验三:分区式存储器管理实验一.实验目的模拟实现一个简单的固定(或可变)分区存储管理系统,进一步加深对分区分配方案设计思想的理解。

二.实验内容(1)建立相关的数据结构,作业控制块、已分配分区及未分配分区;(2)实现一个分区分配算法,如最先适应分配算法、最优或最坏适应分配算法;(3)实现一个分区回收算法;(4)给定一批作业/进程,选择一个分配或回收算法,实现分区存储的模拟管理;(5)将整个过程可视化显示出来。

三.实验步骤(1)任务分析:1、本实验虽然不以前面实验为基础,但建议在其界面中继续增加分区存储管理功能。

2、数据结构:分区说明表,用数组实现。

3、存储管理:建议采取固定分区法管理内存。

编写内存分配、内存回收算法。

(2)程序设计:数据结构设计程序中自由链队列的结点类型可描述如下:structemptylist{intlen, address;//len为分区长度;address为分区起始地址structemptylist *next;//下一个节点};内存占用区用链表描述,其结点类型描述如下:structbusylink{char name;//进程名称intlen , address;//len为分区长度;address为分区起始地址structbusylink *next;//下一个节点};设全程量,设置一个自由链队列和一个占用区队列。

structemptylist *empty_head=NULL; //自由链队列(带头结点)队首指针structbusylink *busy_head=NULL//占用区队列队(带头结点)首指针structbusylink*busy_tail=NULL;// 占用区队列队尾指针(3)程序结果:分配几个内存后,显示其内部的分配进程如下:其中进程S是系统默认分配的进程,内存长度为5.回收过2,4以后显示如下:(4)调试与测试四.实验总结本次实验采用最佳适应算法来分配内存,然后分别输出未进行内存回收时和进行回收时,内存分配情况,进行对比。

实验报告 可变分区 主存分配回收

实验报告 可变分区 主存分配回收
printf("~~~~~~3:退出程序;\n");
printf("========================================\n");
printf("输入你的选择:\n");
scanf("%d",&j);
switch(j)
{
case 1:insertu(i);//为作业分配空间
//合并完之后的空闲分区的结束地址和相邻的空闲分区的起始地址也相连,则继续合并
{
fr[i].len=fr[i].len+fr[i+1].len;
for(k=i+1;k<m-1;k++)
{
fr[k].ad=fr[k+1].ad;
fr[k].len=fr[k+1].len;
fr[k].state=fr[k+1].state;
操作系统实验报告
设计题目
在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收
一、设计内容
主存储器空间的分配和回收。
二、设计目的
一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。主存的分配和回收的实现虽与主存储器的管理方式有关的,通过本实习帮助学生理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
{
while(fr[i].state!='M')

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

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

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

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

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

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

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

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

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

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

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

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

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

可变分区存储管理方式的内存分配和
else
printf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].length,used_table[i].flag);
break;
default:printf("没有该选项\n");
}
}
}
“已分分区表”的结构定义
#define n 10 0”0”1”0”0”1”ength>=xk&&free_table[i].flag==1)if(k==-1||free_table[i].length<free_table[k].length)
k=i;
if(k==-1) ength-xk<=min用来记录空间区和作业占用的区域。
由于可变分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随内存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在内存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收内存分区时,可能会合并空闲分区,这样如果整个内存采用一张表格记录己分分区和空闲区,就会使表格操作繁琐。分配内存时查找空闲区进行分配,然后填写己分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。
{free_table[k].flag=0;
ad=free_table[k].address;
xk=free_table[k].length;
}
else
{free_table[k].length=free_table[k].length-xk;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

试验四存储管理可变分区Document serial number【KKGB-LBS98YT-BS8CB-BSUT-BST108】存储管理实验----可变分区管理实验目的:通过分区存储管理模拟算法,了解可变分区的内存分配和回收过程,熟悉内存分配之最先、最佳、最差适应算法。

实验内容:1.阅读参考程序 ,写出该程序的内存分配算法是哪种2.完善内存回收算法。

3.设计最先内存分配算法,分配从小地址开始;参考程序#include <>#include <>#define n 10 /*假定系统允许的最大作业数为n,假定模拟实验中n值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/#define minisize 100 /*空闲分区被分配时,如果分配后剩余的空间小于minisize,则将该空闲分区全部分配,若大于minisize,则切割分配,即不留小碎片*/ struct{float address; /*已分配分区起始地址*/float length; /*已分配分区长度,单位为字节*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/}used_table[n]; /*已分配区表。

即存放已经分配的分区*/struct{float address; /*空闲区起始地址*/float length; /*空闲区长度,单位为字节*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,可用来登记空闲区,用"1"表示该空闲区未分配*/}free_table[m]; /*空闲区表,即存放空闲分区*//*主存分配函数*/void allocate(char J,float xk) /*给J作业,采用最佳分配算法分配xk大小的空间*/{int i,k;float ad;k=-1;for(i=0;i<m;i++) /*寻找空间大于xk的最小空闲区登记项k*/if(free_table[i].length>=xk && free_table[i].flag==1)if(k==-1||free_table[i].length<free_ta69ble[k].length)k=i;if(k==-1)/*未找到可用空闲区,返回*/{printf("无可用空闲区\n");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<n) /*寻找空表目*/i++;if(i>=n) /*无表目可填写已分配分区*/{printf("无表目填写已分分区,错误\n");/*修正空闲区表*/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;}/*主存分配函数结束*//*主存回收函数*/void reclaim(char 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的作业*/{printf("找不到该作业\n");return;}/*修改已分配表*/used_table[s].flag=0;/*取得归还分区的起始地址S和长度L*/S=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;/*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/while(i<m&&(j==-1||k==-1)){if(free_table[i].flag==1){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)/* 上邻空闲区,下邻空闲区,三项合并*/{。

}else/*上邻空闲区,下邻非空闲区,与上邻合并*/。

elseif(j!=-1)/*上邻非空闲区,下邻为空闲区,与下邻合并*/{。

}else/*上下邻均为非空闲区,回收区域直接填入*//*在空闲区表中寻找空栏目*/t=0;while(free_table[t].flag==1&&t<m)t++;if(t>=m)/*空闲区表满,回收空间失败,将已分配表复原*/{printf("主存空闲表没有空间,回收空间失败\n");used_table[s].flag=J;return;}free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;}return;}/*主存回收函数结束*/int main( ){int i,a;float xk;char J;/*空闲分区表初始化:*/free_table[0].address=10000; /*起始地址假定为10000*/free_table[0].length=10240; /*长度假定为10240,即10k*/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){printf("选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)\n"); printf("选择功项(0~3) :");scanf("%d",&a);switch(a){case 0: exit(0); /*a=0程序结束*/case 1: /*a=1分配主存空间*/printf("输入作业名");do{J=getchar();}while (!(J>='a'&&J<='z'||J>='A'&&J<='Z'));printf("输入作业长度");scanf("%f",&xk);.0f.0fddress,free_table[i].length, free_table[i].flag);printf(" 按任意键,输出已分配区表\n");getchar();printf(" 输出已分配区表:\n起始地址分区长度标志\n");for(i=0;i<n;i++)if(used_table[i].flag!=0)printf("%.0f\t%.0f\t%6c\n",used_table[i].address,used_table[i].length, used_table[i].flag);elseprintf("%.0f\t%.0f\t%6d\n",used_table[i].address,used_table[i].length, used_table[i].flag);break;default:printf("没有该选项\n");}/*case*/}/*While*/}代码:#pragma once#include<iostream>using namespace std;#define n 10 /*假定系统允许的最大作业数为n,假定模拟实验中n值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/#define minisize 100 /*空闲分区被分配时,如果分配后剩余的空间小于minisize,则将该空闲分区全部分配,若大于minisize,则切割分配,即不留小碎片*/class Memory{public:ength >= 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;ength - xk <= minisize){free_table[k].flag = 0;ddress;ength;ength = free_table[k].length - xk;ddress +free_table[k].length; lag != 0 && i<n) /*寻找空表目*/i++;if (i >= n) /*无表目可填写已分配分区*/{cout<<"无表目填写已分分区,错误\n";/*修正空闲区表*/if (free_table[k].flag == 0)lag = 1;ength = free_table[k].length + xk;ddress = ad;used_table[i].length = xk;used_table[i].flag = J;}return;}/*主存回收函数*/void Memory::reclaim(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;}/*修改已分配表*/used_table[s].flag = 0;/*取得归还分区的起始地址S和长度L*/S = used_table[s].address;L = used_table[s].length;j = -1; k = -1; i = 0;/*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/while (i<m && (j == -1 || k == -1)){if (free_table[i].flag == 1)ddress + 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[k].length + S + free_table[j].length;free_table[j].flag = 0;}else/*上邻空闲区,下邻非空闲区,与上邻合并*/free_table[k].length = free_table[k].length + S;elseif (j != -1)/*上邻非空闲区,下邻为空闲区,与下邻合并*/{free_table[s].length += free_table[j].length;free_table[j].flag = 0;}else/*上下邻均为非空闲区,回收区域直接填入*/{/*在空闲区表中寻找空栏目*/t = 0;while (free_table[t].flag == 1 && t<m)t++;if (t >= m)/*空闲区表满,回收空间失败,将已分配表复原*/{printf("主存空闲表没有空间,回收空间失败\n");used_table[s].flag = J;return;}free_table[t].address = S;free_table[t].length = L;free_table[t].flag = 1;}return;}ength > free_table[j].length){int temp = free_table[i].length;free_table[i].length = free_table[j].length;free_table[j].length = temp;temp = free_table[i].address;free_table[i].address = free_table[j].address;free_table[j].address = temp;temp = free_table[i].flag;free_table[i].flag = free_table[j].flag;free_table[j].flag = temp;}}}int k = -1;float ad;ength)&&(free_table[i].flag==1)){k = i;}}if (k == -1){cout <<"无可用分区"<< endl;return;ength - xk <= minisize){free_table[k].flag = 0;ddress;ength;ength = free_table[k].length - xk;ddress + free_table[k].length; lag != 0 && i<n) /*寻找空表目*/i++;if (i >= n) /*无表目可填写已分配分区*/{cout <<"无表目填写已分分区,错误\n";/*修正空闲区表*/if (free_table[k].flag == 0)lag = 1;ength = free_table[k].length + xk;ddress = ad;used_table[i].length = xk;used_table[i].flag = J;}return;}#include<iostream>#include""using namespace std;int main(){Memory M;char J;/*空闲分区表初始化:*/[0].address = 10000; /*起始地址假定为10000*/[0].length = 10240; /*长度假定为10240,即10k*/[0].flag = 1; /*初始空闲区为一个整体空闲区*/for (int i = 1; i<m; i++)[i].flag = 0; /*其余空闲分区表项未被使用*//*已分配表初始化:*/ for (int i = 0; i<n; i++)[i].flag = 0; /*初始时均未分配*/while (1){cout <<"选择功能项:\n0-退出\n1-分配主存\n2-回收主存\n3-显示主存\n";cout <<"选择功项(0~3) :";int a;cin >> a;switch (a){case 0: exit(0); /*a=0程序结束*/case 1: /*a=1分配主存空间*/cout <<"输入作业名:";do{J = getchar();} while (!(J >= 'a'&&J <= 'z' || J >= 'A'&&J <= 'Z'));printf("输入作业长度");float xk;cin >>xk;ddress <<"\t "<< [i].length<<"\t"<< [i].flag << endl;cout<<" 按任意键,输出已分配区表\n\n\n";cout<<" 输出已分配区表:\n起始地址分区长度标志\n";for (int i = 0; i < n; i++)if [i].flag != 0)printf("%.0f\t%.0f\t%6c\n", [i].address, [i].length, [i].flag);elsecout << [i].address <<"\t"<< [i].length<<"\t"<< [i].flag << endl;;break;default:printf("没有该选项\n");}/*case*/}/*While*/return 0;}。

相关文档
最新文档