实验:可变分区存储管理
操作系统实验-可变分区存储管理
作业一实验一 :可变分区存储管理(一) 实验题目编写一个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;}}}(四)程序结果。
实验二 可变分区存储管理
实验二、可变分区存储管理一、实验目的1.加深对可变分区的存储管理的理解;2.提高用C 语言编制大型系统程序的能力,特别是掌握C 语言编程的难点:指针和指针作为函数参数;3.掌握用指针实现链表和在链表上的基本操作。
二、实验内容参照教材P25-P26页内容,编写一个C 程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),用循环首次适应法addr = (char *)lmalloc(unsigned size) 和lfree(unsigned size,char * addr)模拟UNIX 可变分区内存管理,实现对该内存区的分配和释放管理。
三、实验要求分配函数lmalloc 的参数size 和释放函数lfree 的参数size、addr,要以键盘命令的形式输入,每次分配和释放后显示自己的空闲存储区表。
空闲存储区表可采用结构数组的形式(最低要求)或双向链接表的形式,建议采用的数据结构为:struct map{unsigned m_size;char * m_addr;};struct map{unsigned m_size;char *m_addr;struct map *next, *prior;};整个系统的基本框架为程序结束前将整个存储区归还给系统。
四、实验注意事项键盘命令的简单形式如:m[alloc] 100 [enter] 通过lmalloc 函数申请100 字节的内存空间。
f[ree] 100 2567899 [enter] 通过lfree 函数释放起始地址为2567899 的那个内存区,该地址先前通过lmalloc 申请的有效存储区地址。
命令输入可用C语言函数scanf (“%c”, &cmdchar); cmdchar =getchar ( )或scanf (“%s”, &cndstring)后跟scanf (“%u”, &size)或scanf (“%u %u”, &size, &addr)。
实验4:可变分区存储管理
沈阳工程学院学生实验报告(课程名称:操作系统)实验题目:可变分区存储管理班级学号姓名地点f612 指导教师实验日期:一、实验目的通过首次适应算法、最佳适应算法和最坏适应算法实现主存空间的分配,可以使读者可好地理解存储分配算法。
二、实验环境硬件环境:Intel Pentium Processor 1.8G ,512M内存,windows 操作系统软件环境:vc++6.0或Turbo C三、实验内容与要求实验原理:⑴可变分区方式是按作业需要的主存空间大小来分区。
当装入一个作业时,首先要查看是否有足够的空闲空间来分配,若有则按指定的分配方式进行分配;否则作业不能装入。
随着作业的装入和撤离主存空间被分为若干个大大小小的不连续的区间,为了表明各区间的状态可以用一个内存分区表如表1所示来表示。
表1 内存分区表起始地址长度标志120k 20k 作业1200k 50k 空闲这样我们可以定义一个如下的结构表示内存分区信息。
typedef struct node{int start; //起始地址int length; //长度char tag[20]; //标志}job;⑵可变分区的三种算法就是为作业分配主存空间的方法。
●首次适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入第一个满足条件的空间中去。
●最佳适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入满足条件的空闲空间中最小的一个空间中去。
●最坏适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入满足条件的空闲空间中最大的一个空间中去。
从三种算法的说明可以看出,分配空间的过程主要可以分两步:●查询所有满足作业需求的空间块。
●按照指定的算法将作业装入空间块中。
⑶在操作的最初主存空间实际就是一个大的空闲区,不涉及到如何分配的问题。
为直接模拟运行一段时间后主存中出现了多个空闲块的状态,题目要求从一个文件读入空闲区表。
在这里我们可以设计一个空闲区表文件的结构为如表2所示:表2 空闲区表起始地址长度200k 50k……这样也可以方便地将空闲表一次读入程序中,而不必再一个个的输入。
可变分区管理实验
实验三、可变分区内存管理实验环境:实验环境一:Windows平台实验时间:6小时实验目的:体会可变分区内存管理方案,掌握此方案的内存分配过程、内存回收过程和紧凑算法的实现。
实验目标:编制一个程序模拟实现可变分区内存管理。
实验时,假设系统内存容量为1000KB。
分配时使用malloc(pid, length)函数实现,作业释放内存时使用mfree(handle)函数实现,内存情况输出用mlist()函数实现。
实验步骤:1、编写主界面,界面上有三个选项:分配内存、回收内存、查看内存。
选择分配内存时,要求输入作业的进程号和作业长度,然后使用malloc函数分配内存,并报告内存分配结果。
回收内存时要求输入进程号,使用mfree函数实现回收。
查看内存时,使用mlist函数实现输出内存使用情况和空闲情况。
2、编写malloc(pid, length)函数,实现进程pid申请length KB内存,要求程序判断是否能分配,如果能分配,要把分配内存的首地址handle输出到屏幕上。
不能分配则输出字符串“NULL”。
要考虑不能简单分配时,是否符合紧凑的条件,如符合则采用紧凑技术,然后再分配。
分配时可在最佳适应算法、最差适应算法和首次适应算法中任选其一。
3、编写mfree(handle)函数,释放首地址为handle的内存块。
释放成功返回Success,否则返回Failure。
4、编写mlist()函数,要求输出内存使用情况和空闲情况。
输出的格式为:ID Address Length ProcessID 内存分区号Address 该分区的首地址Length 分区长度Process 如果使用,则为使用的进程号,否则为NULL实验结果:实验步骤2的实现过程是:实验步骤2中紧凑算法是如何实现的?实验步骤3中分别要考虑多少种情况?实验步骤3的实现过程是:实验步骤4的实现过程是:实验步骤4的结果是什么?实验报告:(1)完成实验结果中的问题。
可变分区存储管理及可重定位分区存储管理实验报告
可变分区存储管理及可重定位分区存储管理实验报告一、实验目的与要求通过消化理解模拟管理程序,了解存储器的分配与回收过程,体会相关数据结构在实现管理算法中的重要性。
输入一到两组实验数据,观察分配与回收的处理结果,特别是回收时邻接空闲分区的合并处理,检测其算法的正确性。
二、算法思想1、可变分区存储管理(1)算法实现a.分配:查空闲分区链表b.回收:考虑邻接合并(2)实验过程:输入操作命令代码a.分配:输入作业号及作业长度(已建立作业不重复建立)b.回收:输入作业号(不存在作业不释放空间)c .可查看空闲链表情况(检测分配、回收正确性)d.可查看作业表情况(检测分配、回收正确性)2、可重定位分区存储管理在前述可变分区存储管理实验基础上修改实现,即遇大作业存在碎片不够分配时进行合并处理。
注:实现拼接(移动,合并):设立按作业地址排列的有序链表,即用静态链表实现(作业表增加静态链仿真指针),在此基础上按地址从小到大顺序依次向前移动(紧凑处理)。
三、算法实现(可重定位分区存储管理)1、修改相关数据结构(1)作业表增加链接仿真指针int next;分量(2)构造有序静态链表(初始化时next均赋值-1)(3)增加静态链首指针Linkp及空闲总容量计数变量size(注:初始化时Linkp=-1,size=n)2、修改分配函数判断新建立作业长度是否小于等于空闲总容量size值。
若无足够大分区,则先进行合并处理后再分配;若有足够大分区,则按可变分区分配算法处理;若作业长度超过总空闲容量,则产生溢出(无内存)。
3、增加插入排序操作函数(sort_tab())分配新作业空间,则按新作业分区首地址大小,将作业表表项插入静态链表。
回收时,还必须从中删除。
4、增加拼接(移动)操作函数(compact())主要是修改作业表表目内容及空闲分区链表,用模拟操作函数move()进行模拟搬家前移。
5、增加显示静态链表内容的较出操作函数(printsorttab())四、算法流程1、可变分区存储管理(1)主程序(main()函数)(2)分配程序(allocm()函数)(3)回收程序(freem()函数)(4)显示空闲分区链表及作业表程序(printlink()及printtab()函数)注:主程序(main()函数)分配程序(allocm()函数)回收程序(freem()函数)有四种情形(假定回收区首地址=> addr,长度=> length)(1)空闲分区链表空,或不与任何空闲区邻接=> 分配新结点空间,存入回收作业首地址及长度插入空闲分区链(链首,链中,链尾)(2)回收分区与后一空闲分区相邻接=> 进行后邻接合并(3)回首分区与前一空闲分区相邻接(4)回收分区与前同时又与后空闲分区相邻接=> 需进行三个分区合并,并删除一个空闲分区结点注:除了修改空闲分区链表,还要修改作业表(清除flag标志)2、可重定位分区存储管理(1)分配程序(修改allocm()函数)(2)回收程序(修改freem()函数)(3)有序静态链表插入操作程序(sort_tab()函数)(4)拼接(移动)操作程序(compact()函数)(5)输出有序静态链表操作程序(printsorttab()函数)注:分配程序(修改allocm()函数)n,l输出作业已建立提示串,返回内存容量不够,返回置新作业作业表作业地址(分配空间)提示操作者输入新建作业的作业号及长度作业n已建立?l≤size?NYNY分配作业表表项,填入作业长度,置标志为1,总空闲容量减去l查空闲分区链表查到表尾?调用拼接操作函数compact()进行拼接处理Y分区大小=lNYN分区大小>lY修改空闲分区链表(size= l,空闲链为空(一起分配),size> l ,分割分配)作业表表目插入有序静态链表返回切割分配分区空间,修改分区链表作业表表目插入有序静态链表分区整体分配,修改分区链(删除结点)作业表表目插入有序静态链表返回查下一分区N回收程序(修改freem()函数)有序静态链表插入操作程序(sort_tab())拼接(移动)操作程序(compact())五、实验步骤1、可变分区存储管理(1)消化实验算法程序(2)组织上机实验数据(3)第一组:指定(4)第二组:自定(要求能测试各种情形)(5)输入上机程序,编译,运行,记录各操作步骤的运行结果(通过显示空闲分区链表及作业表)2、可重定位分区存储管理(1)阅读相关算法程序(2)组织调试数据(必须包含需合并的操作)(3)上机运行、调试(测试),记录运行情况,分析运行结果六、实验运行情况分析1、可变分区存储管理(1)操作程序1a.分配作业1(80k),作业3(30k),作业8(50k),作业5(140k),作业9(50k),作业6(100k),作业4(50k)b.观察(记录)空闲表及作业表情况c.回收作业8,观察结果d.分配作业7(80k),观察结果e.回收作业6, 回收作业1, 观察结果f分配作业10(120k),观察运行情况g,回收作业7,作业3,作业5,观察各次结果(2)操作程序2a.分配作业1(100k)、作业2(50k)、作业3(50k)、作业4(80k)、作业5(120k),观察结果b.回收作业4c.分配作业6(90k)d.回收作业3 f.分配作业7(140k)2、可重定位分区存储管理(1)操作程序1a.分配作业1(80k),作业3(30k),作业8(50k),作业5(140k),作业9(50k),作业6(100k),作业4(50k)b.观察(记录)空闲表及作业表情况c.回收作业8,观察结果d.分配作业7(80k),观察结果e.回收作业6, 回收作业1, 观察结果f 分配作业10(120k ),观察运行情况g,回收作业7,作业3,作业5,观察各次结果(2)操作程序2a.分配作业1(100k)、作业2(50k)、作业3(50k)、作业4(80k)、作业5(120k),观察结果b.回收作业4c.分配作业6(90k)d.回收作业3 f.分配作业7(140k )七、实验总结通过这次实验,我掌握了可变分区存储管理及可重定位分区存储管理的具体方法,对书本上的理论知识有了更深刻的认识。
实验2:可变分区存储管理
阳工程学院
学生实验报告
(课程名称:操作系统)
实验题目:可变分区存储管理
班级计算机学号姓名
地点F608 指导教师
实验日期: 2017 年 5 月 2 日批阅教师(签字):成绩:
实现过程:
(1)建立文件以a为名字的文件输入如图所示
(2)建立3个空闲分区起始地址和行实现如图所示
(3)显示空闲表和分配表实现如图所示
(4)执行首次算法后,建立的空闲表长度分别为3 8 10,申请一个名为b长度为5的作业故首次适应算法从第二个空闲表首地址为3开始,运行实现如图所示
(5)最佳适应算法,执行首次算法后,建立的空闲表长度分别为3 8 10,申请一个名为c长度为9的作业故最佳适应算法从第二个空闲表首地址为11开始,运行实现如图所示
(6)最坏适应算法,执行首次算法后,建立的空闲表长度分别为3 8 10,申请一个名为d长度为3的作业故最坏适应算法从第二个空闲表首地址为11开始,运行实现如图所示
(7)生成文件a如图所示。
可变分区内存管理实验-题目
可变分区内存管理实习
操作系统实验
1.基本思想
可变分区是指系统不预先划分固定分区,而是在装入程序的时候划分内存区域,使得为程序分配的分区大小恰好等于该程序的需求量,且分区的个数是可变的。
显然可变分区有较大的灵活性,较之固定分区能获得好的内存利用率。
2.数据结构
可变分区管理可以用两种数据结构实现,一种是已分配区表和空闲区表,也就是用预先定义好的系统空间来存放空间分配信息。
另一种也是最常用的就是空闲链表,由于对分区的操作是动态的,所以很难估计数据结构所占用的空间,而且空闲区表会占用宝贵的系统空间,所以提出了空闲链表的概念。
其特点是用于管理分区的信息动态生成并和该分区在物理地址上相邻。
这样由于可以简单用两个空闲块之间的距离定位已分配空间,不仅节约了系统空间,而且不必维护已分配空间的信息。
下图是空闲链表的示意图。
2.实习要求
请实现一个完整的可变分区管理器,包括分配,回收,分区碎片整理等。
希望考虑如下问题:
⏹容错性,当操作出现错误,比如空间不足,空指针引用等的情况下的处理。
⏹空闲块的合并。
⏹已分配空间的跟踪。
当做碎片整理时,需要跟踪分配的空间,修改其引用以保证引用的
正确性。
实验一可变分区存储管理
优点
由于会优先使用更小的空闲区,所以 不会轻易产生大的碎片。
工具介绍
1 2
GCC编译器
用于编译C语言源代码,生成可执行文件。
GDB调试器
用于调试程序,查看程序运行过程中的内存状态、 变量值等信息。
3
Valgrind内存检测工具
用于检测程序中的内存泄漏、越界访问等问题。
实验数据准备
源代码文件
01
实验提供了一份用C语言编写的可变分区存储管理程序的源代码。
测试数据文件
02 可变分区存储管理概述
基本概念
可变分区
在可变分区存储管理中,内存被划分为大小可变的分区,每个分 区可以动态地分配和释放。
分配策略
根据进程的大小和内存的使用情况,选择适当的分配策略,如首次 适应、最佳适应或最差适应等。
分区表
用于记录内存中各个分区的状态、大小、起始地址等信息的数据结 构。
可变分区存储管理的特点
结果分析与讨论
算法优势分析
实验结果表明,本算法在内存分配和 回收过程中具有较高的执行效率和内 存利用率,这主要得益于其采用的先 进的数据结构和算法设计。同时,本 算法还具有良好的稳定性和可扩展性 ,能够适应不同规模的内存管理需求 。
存在问题探讨
尽管本算法在实验中表现出较好的性 能,但仍存在一些需要改进的地方。 例如,在处理大规模内存分配请求时 ,可能会出现性能下降的情况。未来 可以考虑对算法进行进一步优化,提 高其处理大规模请求的能力。
实验2可变分区管理及存储管理
实验2 可变分区管理一、存储管理背景知识1. 分页过程2. 内存共享3. 未分页合并内存与分页合并内存4. 提高分页性能耗尽内存是Windows系统中最常见的问题之一。
当系统耗尽内存时,所有进程对内存的总需求超出了系统的物理内存总量。
随后,Windows必须借助它的虚拟内存来维持系统和进程的运行。
虚拟内存机制是Windows操作系统的重要组成部分,但它的速度比物理内存慢得多,因此,应该尽量避免耗尽物理内存资源,以免导致性能下降。
解决内存不足问题的一个有效的方法就是添加更多的内存。
但是,一旦提供了更多的内存,Windows很可以会立即“吞食”。
而事实上,添加更多的内存并非总是可行的,也可能只是推迟了实际问题的发生。
因此,应该相信,优化所拥有的内存是非常关键的。
1. 分页过程当Windows求助于硬盘以获得虚拟内存时,这个过程被称为分页(paging) 。
分页就是将信息从主内存移动到磁盘进行临时存储的过程。
应用程序将物理内存和虚拟内存视为一个独立的实体,甚至不知道Windows使用了两种内存方案,而认为系统拥有比实际内存更多的内存。
例如,系统的内存数量可能只有16MB,但每一个应用程序仍然认为有4GB内存可供使用。
使用分页方案带来了很多好处,不过这是有代价的。
当进程需要已经交换到硬盘上的代码或数据时,系统要将数据送回物理内存,并在必要时将其他信息传输到硬盘上,而硬盘与物理内存在性能上的差异极大。
例如,硬盘的访问时间通常大约为4-10毫秒,而物理内存的访问时间为60 us,甚至更快。
2. 内存共享应用程序经常需要彼此通信和共享信息。
为了提供这种能力,Windows必须允许访问某些内存空间而不危及它和其他应用程序的安全性和完整性。
从性能的角度来看,共享内存的能力大大减少了应用程序使用的内存数量。
运行一个应用程序的多个副本时,每一个实例都可以使用相同的代码和数据,这意味着不必维护所加载应用程序代码的单独副本并使用相同的内存资源。
可变分区存储管理实验报告
实验三可变分区存储管理
一、实验目的
通过编写可变分区存储模拟系统,掌握可变分区存储管理的基本原理,分区的分配与回收过程。
二、实验内容与步骤
1.打开程序,所得程序界面窗口如图3-1:
图3-1
2.首先选择算法:是否使用搬家算法,可以通过界面上的按钮或算法菜单栏进行
选择;如果不先选择算法,其他功能将被隐藏;注意:在程序执行过程中,不可以重新选择算法。
3.进行初始化:设置内存大小,可以选择默认值400KB;确定内存大小前,其他
操作将被屏蔽。
4.初始化内存大小以后,就可以进行添加进程操作。
5.添加一个进程后,撤消进程功能被激活,可以撤消一个选定的进程或所有的进
程(图3-2)
图3-2
6.查询功能:可以通过按钮或菜单栏显示内存状态图形、空闲区图表,还可以在内存状态条里闪烁显示某一在空闲区图表选中的空闲区。
7.内存不足但经过搬家算法可以分配内存空间给进程,将有如下(图3-3)提示:
图3-3
8.内存空间不足也有相应提示。
9.重置或退出。
三、实验结果
第一至四组数据测试采用搬家算法,第二至八组数据测试不采用搬家算法。
第一组测试数据:(测试内存错误输入) 选择搬家算法,内存大小:0KB/-50KB/空
第二组测试数据:(测试内存空间不够)选择搬家算法,内存大小:400KB
第三组测试数据:(测试是否采用最佳适应法)选择搬家算法,内存大小:200KB 第四组数据:(测试搬家算法)选择搬家算法,内存大小:400KB
第五组数据至第八组数据:不采用搬家算法,内存大小:分别与第一至第四组数据相同,操作过程:分别与第一至第四组数据相同。
可变分区存储管理实验报告
沈阳工程学院学生实验报告实验室名称:信息工程系信息安全实验室实验课程名称:操作系统实验项目名称:可变分区存储管理班级:计专本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();}。
可变分区存储管理+实验报告+程序+设计思路和感悟
实验题目:可变分区存储管理一、实验目的可变分区存储管理方式是操作系统中存储管理的重要方式,其主要思想是用户作业进行连续存储,每次按照用户的请求,如果内存中有能满足用户作业大小的空闲区,就采用不同的算法分配给用户,否则,不分配,可变分区容易产生外零头。
分区分配算法包括最佳适应算法、最坏适应算法、首次适应算法等。
通过本实验可加深学生对存储器管理方式的把握以及分配算法的理解,并提高程序设计的能力。
二、实验环境个人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其中,起始地址指出个空闲区的内存起始地址,长度指出空闲区的大小。
可变分区存储管理
实验一可变分区存储管理一、实验内容编写程序模拟内存分配与回收的过程。
二、实验目的1.加深对可变分区的存储管理的理解;2.提高用C语言编制大型系统程序的能力,特别是掌握C语言编程的难点:指针和指针作为函数参数;3.掌握用指针实现链表和在链表上的基本操作。
三、实验题目编写一个C程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),模拟可变分区内存管理,实现对该内存区的分配和释放管理。
(1)设计思路用char*malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),用循环首次适应法addr = (char *)lmalloc(unsigned size)和lfree(unsigned size,char * addr)模拟UNIX 可变分区内存管理,实现对该内存区的分配和释放管理。
(2)循环首次适应算法模拟UNIX 的进程管理程序采用的是循环首次适应算法,具体算法如下: 系统每次为进程分配资源时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业。
(3)数据结构(4)系统总体框图四、源程序代码#include <iostream.h> #include <string.h>#include <stdio.h>#include <stdlib.h>#include <conio.h>#define getpch(type) (type*)malloc(sizeof(type))#define maxm 600 /* 最大内存空间*/#define null 0struct spd{ /* 分区说明表 */int j; /*分区名*/int len; /*大小*/char state; /*状态:'e','f','a'*/int saddre; /*起始地址*/struct spd *next;}*rspd=null,*p;struct jcb{char name[10];int xk;int sadd;struct jcb *next;}*jp,*ready;typedef struct spd SPD;typedef struct jcb JCB;void mainmenu();void input();void disp0();void disp();void initm();void allationm();void freem();void initm(){/*初始化*/p=getpch(SPD);p->j=1;p->len=maxm;p->state='e';p->saddre=0;rspd=p;rspd->next=null;}void disp2(){JCB *first;first=ready;if(ready!=null){printf("\n内存中现有作业:\n");while(first!=null){printf("%s\t",first->name);i++;if(i==5)printf("\n");first=first->next;}}else printf("内存中无作业.\n");}void input(){ JCB *first;int xk;char name[10];first=ready;printf("\n请输入作业名:");scanf("%s",&name);while(first!=null){if(strcmp(name,jp->name)==0){printf("\n此文件名已存在,请重新输入:"); scanf("%s",&name);}else first=first->next;}first=ready;printf("\n请输入作业所需的内存空间:");scanf("%d",&xk);if(xk>600||xk<0){printf("\n请重新输入作业所需的内存空间:"); scanf("%d",&xk);}jp=getpch(JCB);strcpy(jp->name,name);jp->sadd=null;if(ready==null){/* 排序 */ready=jp;ready->next=null;}else{while(first->next!=null){first=first->next;}first->next=jp;first=first->next;first->next=null;}}void allationm(){int flag=0;SPD *first;first=rspd;input();while(first!=null){if(first->state=='e'&&first->len>=jp->xk){ jp->sadd=first->saddre;first->state='f';if(first->len>jp->xk){p=getpch(SPD);p->j=first->j+1;p->len=first->len-jp->xk;first->len=jp->xk;p->saddre=first->saddre+jp->xk;p->state='e';p->next=first->next;first->next=p;flag=1;while(p->next!=null){p->next->j=p->next->j+1;p=p->next;}}}else first=first->next;if(flag==1)break;}if(first==null){printf("内存不足.\n");getch();}}void freem(){ JCB *first,*second,*pp;SPD *pre;int add=null,i;int flag=0,flag1=0;long temp;disp2();printf("\n请输入要撤销的作业名:");jp=getpch(JCB);scanf("%s",&jp->name);jp->sadd=null;jp->xk=null;jp->next=null; pre=rspd;p=pre->next;first=ready;second=first->next;/*寻找要撤销的作业,并撤销它*/if(strcmp(first->name,jp->name)==0){flag=1;ready=second;first->next=null;add=first->sadd;free(first);}while(flag==0&&second!=null){if(strcmp(second->name,jp->name)==0) {flag=1;first->next=second->next;second->next=null;add=second->sadd;free(second);break;}if(second->next!=null){first=first->next;second=second->next;}else break;}/*找出作业的内存地址,释放之*/if(add==pre->saddre&&flag==1){flag1=1;pre->state='e';if(p->state=='e'){pre->len=p->len+pre->len;pre->next=p->next;p->next=null;while(pre->next!=null){pre->next->j=pre->next->j-1;pre=pre->next;}free(p);}}while(flag==1&&flag1==0&&p!=null){i=add;pp=ready;if(add==p->saddre){flag1=1;p->state='e';if(pre->state=='e'){if(p->next!=null&&p->next->state=='e'){pre->len=pre->len+p->len+p->next->len; pre->next=p->next;p->next=null;free(p);p=pre->next;pre->next=p->next;p->next=null;free(p);p=rspd;while(pre->next!=null){pre->next->j=pre->next->j-2; pre=pre->next;}}else{pre->len=p->len+pre->len;pre->next=p->next;p->next=null;free(p);while(pre->next!=null){pre->next->j=pre->next->j-1; pre=pre->next;}}}else {if(p->next!=null&&p->next->state=='e'){ p->len=p->len+p->next->len;p->state='e';pre=p->next;p->next=p->next->next;pre->next=null;free(pre);while(p->next!=null){p->next->j=p->next->j-1;p=p->next;}}else p->state='e';}}/*if*/if(flag1==1)break;p=p->next;pre=pre->next;}/*while*/if(flag==0)printf("\n作业不存在,无法撤消.\n");if(flag1==1){printf("\n...正在撤消\n");for(temp=1;temp<=30000000;temp++){};printf("作业撤消完毕.\n");}free(jp);disp0();void disp0(){/*显示空闲链表*/JCB *first;first=ready;printf("\n主存空间的分配情况为:\n");printf("分区号作业名起始地址分区大小分配情况\n"); p=rspd;while(p!=null){printf("%4d ",p->j);if(ready!=null&&p->state=='f'){if(first!=null){printf("\t%s",first->name);first=first->next;}}if(p->state=='e')printf("\t\t%4d kB",p->saddre);elseprintf("\t%4d kB",p->saddre);printf("\t %4d kB",p->len);if(p->state=='e')printf(" 未分配");if(p->state=='f')printf(" 已分配");printf("\n");p=p->next;}}void disp(){ disp0();printf("按任意键返回选择执行操作.\n");getch();}void main(){/*界面*/initm();int c;printf(" ****************************\n");printf(" * 主存空间的分配与回收 *\n");printf(" ****************************\n");printf(" 1.分配内存 2.回收内存 3.显示分配 4.退出\n");while(1){printf("\n请选择要执行的操作(1~4):");scanf("%d",&c);if(c>4||c<1){printf("输入错误,请重新输入:\n");continue;}switch(c){case 1:allationm(); break;case 2:if(ready!=null)freem();else {printf("\n内存中没有作业.\n");getch();}break;case 3:disp();break;case 4:goto end;}}end:getchar();}五、程序运行时初值和运行结果1.运行结果(1)初始界面(2)分配内存演示结果(3)显示分配演示结果(4)回收内存演示结果六、实验总结通过本次实验加深了对循环首次适应算法,内存分配与回收的机制的理解,也巩固了C++程序语言设计的基础。
实验上机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、处理流程设计参数说明:形、变参数的区分按参数的逻辑意义认定。
实验一+可变分区存储管理
实验一 可变分区存储管理(一) 实验题目编写一个C 程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),模拟可变分区内存管理,实现对该内存区的分配和释放管理。
(二) 实验目的1.加深对可变分区的存储管理的理解;2.提高用C 语言编制大型系统程序的能力,特别是掌握C 语言编程的难点:指针和指针作为函数参数;一) 实验题目编写一个C 程序,用char *malloc(unsigned size)函数向系统申请一次内存空间(如size=1000,单位为字节),用循环首次适应法addr = (char *)lmalloc(unsigned size) 和lfree(unsigned size,char * addr)模拟可变分区内存管理,实现对该内存区的分配和释放管理。
(二) 实验目的1.加深对可变分区的存储管理的理解;2.提高用C 语言编制大型系统程序的能力,特别是掌握C 语言编程的难点:指针和指针作为函数参数;3.掌握用指针实现链表和在链表上的基本操作。
(三) 实验要求(a)(b)(c)(d)图2-9释放区与前后空闲区相邻的情况要分配函数lmalloc的参数size和释放函数lfree的参数size、addr以键盘命令的形式输入,每次分配和释放后显示自己的空闲存储区表。
空闲存储区表可采用结构数组的形式(基本要求),或双向链接表的形式(提高一步),建议采用的数据结构为:结构数组的形式:struct map {unsigned m_size;char * m_addr;};struct map coremap[N];或双向链接表的形式:struct map {unsigned m_size;char *m_addr;struct map *next, *prior;};struct map *coremap;整个系统的基本框架为:程序结束前将整个存储区归还给系统。
可变分区存储管理方式的内存分配和回收实验报告
可变分区存储管理方式的内存分配和回收实验报告【实验报告】一、实验目的了解可变分区存储管理方式的内存分配和回收过程,了解最优算法的原理和实现方法,掌握最优算法在可变分区存储管理方式下的内存分配和回收操作。
二、实验原理最优算法的分配过程如下:1.初始化内存分区表,将整个内存分为一个未分配的分区。
2.当有新的进程请求内存时,遍历内存分区表,选择满足分配条件且剩余空间最小的分区进行分配。
3.更新分区表中相应分区的空闲空间,并将分配出去的空间标记为已分配。
最优算法的回收过程如下:1.当一些进程结束或释放内存时,遍历分区表,找到对应的已分配分区。
2.将该分区标记为空闲,并进行合并操作,合并相邻的空闲分区。
3.更新分区表。
三、实验步骤1.初始化内存分区表,将整个内存设为一个未分配的分区。
2.依次输入若干个进程的大小。
3.按照最优算法进行内存分配和回收。
4.输出每个进程分配的内存空间和内存分区表的状态。
四、实验结果与分析输入进程大小为:{100KB,200KB,50KB,150KB}初始内存分区表:{未分配,800KB}进程1申请100KB,满足分配条件的最小剩余空间为300KB,分配给进程1后,更新分区表:分配给进程1的内存:{100KB}更新后的内存分区表:{已分配,未分配,700KB}进程2申请200KB,满足分配条件的最小剩余空间为300KB,分配给进程2后,更新分区表:分配给进程2的内存:{200KB}更新后的内存分区表:{已分配,已分配,未分配,500KB}进程3申请50KB,满足分配条件的最小剩余空间为150KB,分配给进程3后,更新分区表:分配给进程3的内存:{50KB}更新后的内存分区表:{已分配,已分配,已分配,未分配,450KB}进程4申请150KB,满足分配条件的最小剩余空间为150KB,分配给进程4后,更新分区表:分配给进程4的内存:{150KB}更新后的内存分区表:{已分配,已分配,已分配,已分配,未分配,300KB}进程2结束,释放内存,回收进程2占用的空间,更新分区表:释放进程2的内存:{200KB}合并空闲分区后的内存分区表:{已分配,已分配,未分配,300KB}进程3结束,释放内存,回收进程3占用的空间,更新分区表:释放进程3的内存:{50KB}合并空闲分区后的内存分区表:{已分配,未分配,300KB}进程1结束,释放内存,回收进程1占用的空间,更新分区表:释放进程1的内存:{100KB}合并空闲分区后的内存分区表:{未分配,400KB}进程4结束,释放内存,回收进程4占用的空间,更新分区表:释放进程4的内存:{150KB}合并空闲分区后的内存分区表:{未分配,550KB}五、实验总结通过本次实验,我对可变分区存储管理方式的内存分配和回收过程有了更深入的了解。
操作系统实验报告可变分区存储管理方式的内存分配回收
操作系统实验报告可变分区存储管理方式的内存分配回收集团文件发布号:(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");}五.实验结果与体会我的体会:。
操作系统实验报告可变分区存储管理方式的内存分配回收
操作系统实验报告可变分区存储管理方式的内存分配回收可变分区存储管理方式是一种常见的内存分配和回收策略,通过将内存分成若干大小不等的分区,分配给不同大小的进程使用。
本文将对可变分区存储管理方式的内存分配和回收进行详细介绍。
首先,可变分区存储管理方式需要对内存进行划分,将内存分成若干个大小不等的分区。
这些分区可以是固定大小的,也可以是可变大小的。
当进程申请内存时,系统会根据申请内存的大小来选择一个合适大小的分区进行分配。
分配时分为两种情况:首次适应和最佳适应。
首次适应算法是指从内存的起始位置开始遍历分区,找到第一个能满足进程要求的分区进行分配。
这种算法的优点是找到满足条件的分区速度较快,缺点是容易造成较大的内存碎片。
最佳适应算法是指通过遍历整个内存,找到一个大小最接近进程要求的分区进行分配。
这种算法的优点是能够减小内存碎片的产生,但是分配速度较慢。
当进程结束时,需要回收其占用的内存。
对于可变分区存储管理方式,在回收内存时出现了两种情况:内部碎片和外部碎片。
内部碎片是指分配给进程的分区中,有一部分空闲内存无法被其他进程利用。
这是因为当一些进程需要分配内存时,分配的大小可能大于其实际需要的大小,导致分区中留下了空余空间。
解决内部碎片的方法是动态地调整分区的大小,使其能够更好地适应进程的大小需求。
外部碎片是指存储空闲的分区之间的一些不可利用的内存。
当进程需要分配内存时,可能没有一个分区能满足其大小需求,导致无法分配内存。
解决外部碎片的方法是内存紧缩和分区合并。
内存紧缩是指将内存中的进程向一端移动,使剩余的空闲内存空间连在一起。
这样可以使得所有的空闲内存空间都可以被利用,减少外部碎片的产生。
分区合并是指将不连续的空闲分区进行合并,形成更大的连续空闲分区。
这样可以提供给大型进程使用,减少外部碎片的产生。
综上所述,可变分区存储管理方式的内存分配和回收是一个动态的过程,需要根据进程的需求进行灵活地管理。
它可以通过首次适应或最佳适应算法选择合适的分区进行内存分配,通过动态调整分区大小解决内部碎片问题,并通过内存紧缩和分区合并减少外部碎片的产生。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
沈阳工程学院
学生实验报告
(课程名称:操作系统)
实验题目:存储管理1
班级网络本121 学号2012418118 姓名杨挺地点F608 指导教师吕海华祝世东
实验日期: 2014 年 5 月27 日
else
break;
}
switch(n)
{
case 0:printf("感谢您的使用!再见!\n");exit(0);
case 1:view();break;
case 2:earliest();break;
case 3:excellent();break;
case 4:worst();break;
}
system("cls");
}
}
运行结果:
(1)建立3个空闲分区起始地址和行实现如下图所示:
(2)显示空闲表和分配表实现如下图所示:
(3)执行首次算法后,建立的空闲表长度分别为5 6 7,申请一个名为b长度为5的作业故首次适应算法从第二个空闲表首地址为1开始,运行实现如下图所示:
(4)最佳适应算法,执行首次算法后,建立的空闲表长度分别为5 6 7,申请一个名为b长度为7的作业故首次适应算法从第二个空闲表首地址为3开始,运行实现如下图所示:
(5) 最坏适应算法,执行首次算法后,建立的空闲表长度分别为5 6 7,申请一个名为b长度为6的作业故首次适应算法从第二个空闲表首地址为2开始,运行实现如图下所示:
20 / 21。