首次适应算法实验报告
采用首次适应算法的动态分区分配模拟课程设计实验报告
1 需求分析1)本程序要求实现对内存的动态分配与回收的模拟,同时,在内存的分配时还必须使用首次适应算法,最后,还要显示内存块分配和回收后空闲内存分区链的情况。
2)要实现对作业的内存分配,首先要有一个对作业进行创建和分配内存的模块,其中,该模块在分配内存时要使用首次适应算法;要实现对内存的回收,要有一个内存回收的模块,其中,该模块在回收内存时要考虑内存回收的四种情况;最后,还要有一个能显示内存空闲分区链的情况的模块。
2 概要设计1)首次适应算法的结构如图1:图1 首次适应算法的结构图2)数据结构:struct Fq{int size,o,no;Fq *before,*next;};其中,Fq表示结构体的名字(类型),size表示分区的可用空间大小,o表示该分区的状态(是否已分配),no表示该分区中的作业标志,*before表示该结点的向前指针,*next表示该结点的向后指针。
3)各种函数说明:void alloc(int b,int no,Fq *p);对作业no进行内存分配的功能函数;其中,参数b表示需求的内存大小,参数no表示作业的编号,参数*p表示空闲分区链的第一个非空结点的指针;void free(Fq *c);将地址为c的分区的内存回收;其中,参数*c表示要回收内存的结点;void create(Fq *head);创建新作业的子函数;其中,参数*head表示空闲分区链的链首指针;要配合函数alloc()使用;void cha(Fq *head);查看内存中的空闲分区链的子函数;其中,参数*head表示空闲分区链的链首指针;void hui(Fq *head);回收内存的子函数;其中,参数*head表示空闲分区链的链首指针;要配合函数free()使用;3 运行环境1)操作系统: Windows XP ( 32位 / DirectX 11 )2)电脑: X86 兼容台式电脑处理器: 英特尔 Pentium(奔腾) 双核 E5300 @ 2.60GHz内存: 2 GB4 开发工具和编程语言1)开发工具:Visual C++ 6.0;2)编程语言:C++语言;5 详细设计1)程序结构如图2:图2 程序结构图2)●主菜单模块:void main()//主函数{Fq *head=new Fq;head->next=new Fq;head->next->size=MAXSIZE;head->next->o=0;head->next->next=NULL;int choice=0;do{cout<<"请选择你要进行的操作:"<<endl;cout<<"1、创建新作业 2、查看空闲分区链 3、回收内存空间 0、退出"<<endl;cin>>choice;switch(choice){case 1: create(head);break;case 2: cha(head);break;case 3: hui(head);break;case 0: break;default: cout<<"输入错误!"<<endl;}}while(choice!=0);}●创建新作业模块:void create(Fq *head)//创建作业子函数{Fq *p=head->next;p->before=head;int no=0,b=0;cout<<"请输入要创建的作业的编号:";cin>>no;cout<<"请输入作业的需求空间大小:";cin>>b;alloc(b,no,p);//此处调用功能函数alloc()}●查看空闲分区链模块:void cha(Fq *head)//查看内存中的空闲分区链的子函数{Fq *p=head->next;p->before=head;int i=0;cout<<"空闲分区链的情况为:"<<endl;while(p!=NULL){if(p->o==0){cout<<"空闲分区"<<++i<<" "<<p->size<<"K"<<endl;}p=p->next;}}●回收内存空间模块:void hui(Fq *head)//回收内存的子函数{Fq *p=head->next;p->before=head;int no=0;cout<<"请输入要回收内存的作业号:";cin>>no;while(p!=NULL){if(p->no==no){free(p);//此处调用功能函数free()cout<<"作业"<<no<<"的内存已回收!"<<endl;return ;}else p=p->next;}}●内存分配功能函数模块:void alloc(int b,int no,Fq *p)//对作业no进行内存分配的子函数{while(p!=NULL){if(p->o==1) {p=p->next;}else{if(p->size>b){if(p->size-b<=min_size){p->o=1;p->no=no;}else{Fq *q=new Fq;Fq *r;r=p->before;r->next=q;q->before=r;q->next=p;p->before=q;q->size=b;p->size=p->size-b;q->no=no;q->o=1;}cout<<"内存分配成功!"<<endl;return ;}else p=p->next;}}cout<<"内存分配失败!"<<endl;}●内存回收功能函数模块:void free(Fq *c)//将地址为c的分区内存回收{if(c->before->o==0&&c->next->o==0){Fq *r=c->before,*s=c->next->next;r->size=(r->size+c->size+c->next->size);r->next=s;if(s!=NULL) s->before=r;}if(c->before->o==0&&c->next->o!=0){c->before->size=c->before->size+c->size;c->before->next=c->next;c->next->before=c->before;}if(c->next->o==0&&c->before->o!=0){Fq *r=c->next->next;c->size=c->size+c->next->size;c->next=c->next->next;if(r!=NULL) r->before=c;c->o=0;}else c->o=0;}6 调试分析1)内存分配功能函数模块:刚开始对作业分配内存时,只是将空闲分区的大小以及前后向指针进行修改,而没有对分配给作业的内存进行设置;这样,尽管内存的空闲分区大小已经变小,但是,以后却无法对已分配的内存空间以及作业进行修改;于是,我经过思考后,决定将分配给作业的内存空间也设置为一个分区,只不过不是空闲的分区,通过状态标识符o来与空闲分区进行区别。
存储器管理实验实验报告
存储器管理实验实验报告一、实验目的存储器管理是操作系统的重要组成部分,本次实验的目的在于深入理解存储器管理的基本原理和方法,通过实际操作和观察,掌握存储器分配与回收的算法,以及页面置换算法的实现和性能评估。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验内容与步骤(一)存储器分配与回收算法实现1、首次适应算法(1)原理:从空闲分区链的首地址开始查找,找到第一个满足需求的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态(已分配或空闲)。
当有分配请求时,从链表头部开始遍历,找到第一个大小满足需求的空闲分区。
将该分区进行分割,一部分分配给请求,剩余部分仍作为空闲分区留在链表中。
若找不到满足需求的空闲分区,则返回分配失败。
2、最佳适应算法(1)原理:从空闲分区链中选择与需求大小最接近的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。
当有分配请求时,遍历整个链表,计算每个空闲分区与需求大小的差值。
选择差值最小的空闲分区进行分配,若有多个差值相同且最小的分区,选择其中起始地址最小的分区。
对选中的分区进行分割和处理,与首次适应算法类似。
3、最坏适应算法(1)原理:选择空闲分区链中最大的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。
当有分配请求时,遍历链表,找到最大的空闲分区。
对该分区进行分配和处理。
(二)页面置换算法实现1、先进先出(FIFO)页面置换算法(1)原理:选择在内存中驻留时间最久的页面进行置换。
(2)实现步骤:建立页面访问序列。
为每个页面设置一个进入内存的时间戳。
当发生缺页中断时,选择时间戳最早的页面进行置换。
2、最近最久未使用(LRU)页面置换算法(1)原理:选择最近一段时间内最长时间未被访问的页面进行置换。
实验三 最佳适应算法 实验报告
最佳适应算法实验报告一、实验目的了解首次适应算法、最佳适应方法、最差适应算法二、实验方法修改Minix操作系统的内存分配源码,实现最佳适应算法三、实验任务修改Minix操作系统中的内存分配源码,将首次适应算法更改为最佳适应算法。
重新编译系统映像文件,观察实验结果。
四、实验要点内存分配、首次适应算法、最佳适应算法。
五、实验内容5.1 minix内存分配源码安装好minix操作系统以后,minix系统的源码位于/usr/src目录中。
其中,与内存分配的相关源码则在/usr/src/servers/pm/alloc.c中。
minix系统初始的内存分配算法为首次适应算法。
在minix系统中,空闲的内存空间信息采用链表的信息储存起来,而操作系统分配内存空间的过程则是在这个链表中寻找一个合适空间,返回内存空间的地址,再更改链表中的内存空间信息。
这就是minix系统分配内存的实质。
5.2分析首次适应算法首次适应算法,指的从空闲内存块链表的第一个结点开始查找,把最先找到的满足需求的空闲内存块分配出去。
这种算法的优点是分配所需的时间较短,但这种算法会形成低地址部分形成很多的空间碎片,高地址区保留大量长度较长的空闲内存块。
内存分配的操作在/usr/src/servers/pm/alloc.c源文件中的alloc_mem函数中完成。
在函数的初始位置,定义了两个用于遍历链表的指针变量,两个指针变量的定义如下:registerstruct hole *hp, *prev_ptr;而hole结构体的定义如下:PRIVATE struct hole {struct hole *h_next;phys_clicksh_base;phys_clicksh_len;} hole[NR_HOLES];先分析这个结构体的定义,这个结构体中,有三个变量,h_next是一个指向链表下一个结点的指针变量;h_base则是指向这个链表所表示的空闲内存空间的地址,h_len 则是这个空闲内存空间的长度;phys_clicks的定义可以在/usr/src/include/minix/type.h 中找到,phys_clicks的定义为:typedef unsigned intpyhs_clicks;phys_clicks其实就是无符号的整数类型。
操作系统存储管理实验报告
操作系统存储管理实验报告一、实验目的本次实验的目的是通过编写一段程序,实现对内存的分配和回收操作,并验证算法的正确性和性能。
二、实验内容1.实现首次适应算法首次适应算法是一种动态分配的内存管理算法,通过从低地址往高地址内存块,找到第一个满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,根据需求大小找到第一个合适的空闲块,并在其前后设置相应的标志位;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
2.实现最佳适应算法最佳适应算法是一种动态分配的内存管理算法,通过整个内存空间,找到最小的满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,遍历整个内存空间,找到满足需求且大小最小的空闲块进行分配;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
三、实验结果1.首次适应算法经过测试,首次适应算法能够正确地进行内存的分配和回收操作,并且算法的性能良好。
尽管首次适应算法在分配过程中可能会产生碎片,但是由于它从低地址开始,可以在较短的时间内找到满足需求的空闲块。
在实际应用中,首次适应算法被广泛采用。
2.最佳适应算法经过测试,最佳适应算法能够正确地进行内存的分配和回收操作,并且算法的性能较好。
最佳适应算法会整个内存空间,找到大小最小的满足需求的空闲块。
因此,在分配过程中不会产生很多的碎片,但是算法的执行时间较长。
四、实验总结通过本次实验,我们成功地实现了首次适应算法和最佳适应算法,并对算法的正确性和性能进行了验证。
两种算法在内存的分配和回收过程中都表现出良好的性能,可广泛应用于实际场景中。
实验四操作系统存储管理实验报告
实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。
二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。
三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。
在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。
2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。
为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。
3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。
同样通过对空闲分区链表的排序和查找来实现。
(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。
在模拟过程中,使用一个队列来记录页面的进入顺序。
2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。
通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。
3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。
四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。
2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。
3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。
操作系统 首次最佳适应算法
学号专业姓名实验日期教师签字成绩实验报告【实验名称】采用可变式分区管理,使用首次获最佳适应算法实现内存分配与回收【实验目的与原理】1、理解首次获最佳适应算法的内涵,并熟练掌握该算法。
2、学会可变式分区管理的原理是即在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。
3、当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区没有时应将空闲区一分为二。
为了便于快速查找,要不断地对表格进行紧缩,即让“空表目”项留在表的后部。
4、当一个作业执行完成时,作业所占用的分区应归还给系统。
作业的释放区与空闲区的邻接分以下四种情况考虑:①释放区下邻(低地址邻接)空闲区;②释放区上邻(高地址邻接)空闲区③释放区上下都与空闲区邻接;④释放区与空闲区不邻接。
【实验内容】#include<stdio.h>#include<iostream>#include<string>using namespace std;const int MAXJOB=100;//定义表最大记录数typedef struct node{int front;int length;char data[20];}job;job frees[MAXJOB];//定义空闲区表int free_quantity;job occupys[MAXJOB];//定义已分配区表int occupy_quantity;//初始化函数void initial(){int i;for(i=0;i<MAXJOB;i++){frees[i].front=-1;frees[i].length=0;strcpy(frees[i].data,"free");occupys[i].front=-1;occupys[i].length=0;strcpy(occupys[i].data," ");}free_quantity=0;occupy_quantity=0;}//创建空闲分区表int creatfree(){FILE *fp;char fname[20];cout<<"请输入空闲区数据文件来源的文件名:"; cin>>fname;if((fp=fopen(fname,"r"))==NULL){cout<<"错误,文件打不开,请检查文件名"<<endl; }else{while(!feof(fp)){fscanf(fp,"%d\t%d\n",&frees[free_quanti ty].front,&frees[free_quantity].length);free_quantity++;}cout<<"空闲的分区表已建立!\n";return 1;}return 0;}void sort()//将free空间安首地址从小到大的顺序排列{int i,j,p;for(i=0;i<free_quantity-1;i++){p=i;for(j=i+1;j<free_quantity;j++){if(frees[j].front<frees[p].front){p=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}//显示函数void show(){int i;cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前空闲表:"<<endl;cout<<" 起始地址长度状态"<<endl;for(i=0;i<free_quantity;i++){cout.setf(2);cout.width(12);cout<<frees[i].front;cout.width(10);cout<<frees[i].length;cout.width(8);cout<<frees[i].data<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前已分配表:"<<endl;cout<<" 起始地址长度占用作业名"<<endl;for(i=0;i<occupy_quantity;i++){cout.setf(2);cout.width(12);cout<<occupys[i].front;cout.width(10);cout<<occupys[i].length;cout.width(8);cout<<occupys[i].data<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl;}//最先适应分配算法void assign(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length)//如果空闲空间I的长度〉作业长度{flag=1; //空闲标志位就置1 }}if(flag==0){cout<<endl<<"对不起,当前没有能满足你申请长度的空闲内存,请稍候再试!"<<endl;}else{t=0;i=0;while(t==0)//为空闲区间的时候{if(frees[i].length>=job_length){t=1;}i++;//如果空闲空间I的长度不大于作业长度,I加一,判断下一个空间}i--;occupys[occupy_quantity].front=frees[i] .front;strcpy(occupys[occupy_quantity].data,jo b_name);occupys[occupy_quantity].length=job_len gth;occupy_quantity++;if(frees[i].length>job_length)//如果空间的长度大于作业的长度,{frees[i].front+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}//撤消作业void cancel(){char job_name[20];int i,j,flag,p=0;int front;int length;cout<<"请输入要撤消的作业名:";cin>>job_name;flag=-1;for(i=0;i<occupy_quantity;i++){if(!strcmp(occupys[i].data,job_name))//当输入作业名匹配时{flag=i;front=occupys[i].front;length=occupys[i].length;}}if(flag==-1){cout<<"没有这个作业名"<<endl;}else{//加入空闲表for(i=0;i<free_quantity;i++){if((frees[i].front+frees[i].length)==fr ont)//上空{if(((i+1)<free_quantity)&&(frees[i+1].f ront==front+length))//下空{frees[i].length=frees[i].length+frees[i +1].length+length;for(j=i+1;j<free_quantity;j++){frees[j]=frees[j+1];}free_quantity--;p=1;}else{frees[i].length+=length;p=1;}}if(frees[i].front==(front+length))//下空上不空{frees[i].front=front;frees[i].length+=length;//第i 个空闲区间的长度=第i个空闲区间的长度+lengthp=1;}}if(p==0)//上下空闲区都不空{frees[free_quantity].front=front;frees[free_quantity].length=length;free_quantity++;}//删除分配表中的该作业for(i=flag;i<occupy_quantity;i++){occupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int flag=0;int t=1;int chioce=0;cout<<"*********** xxxxxxxxx***********\n"; initial();flag=creatfree();while(flag==1){sort();cout<<" 可变分区存储管理模拟系统"<<endl;cout<<" 1.申请空间 "<<endl;cout<<" 2.撤消作业 "<<endl;cout<<" 3.显示空闲表和分配表"<<endl;cout<<" 0.退出"<<endl;cout<<"请选择:";cin>>chioce;switch(chioce){case 1:assign();break;case 2:cancel();break;case 3:show();break;case 0:flag=0;break;default:cout<<"选择错误!"<<endl;}}}实验结果显示:【实验小结】本实验难度在两个方面,一是首次最佳适应算法assign(),这里我用的是结构体数组来存储空闲分区;二是对已分配分区的释放,这里同样采取结构体数组来存储已分配分区,用cancle()函数来实现。
动态分区分配方式首次适应算法
动态分区分配方式首次适应算法首次适应算法的思想是,当进程请求分配内存时,从空闲内存中找到第一个大小足够的空闲分区来满足进程需求。
因此,首次适应算法的时间复杂度与空闲分区的数量有关,但是分配成功的速度相对较快。
首先,我们需要建立一个空闲分区链表,其中记录了每个空闲分区的起始地址和大小。
初始状态下,整个内存空间是一个空闲分区。
当进程请求分配内存时,首次适应算法按照分区链表的顺序遍历空闲分区,找到第一个大小满足进程需求的分区。
具体操作如下:1.遍历空闲分区链表,找到第一个空闲分区大小大于等于进程请求大小的分区。
如果找到了满足条件的分区,则进行下一步;如果遍历完成仍未找到满足条件的分区,则进行内存紧缩或置换策略,为进程分配内存。
2.将找到的空闲分区进行分割,分为已分配给进程的部分和剩余的空闲部分。
已分配给进程的部分可以是与进程请求大小相等的分区,也可以是稍大的分区,以便于使用剩余空间。
3.更新空闲分区链表。
将已分配给进程的部分从链表中删除,将剩余的空闲分区插入链表中的适当位置。
4.返回已分配给进程的内存起始地址。
当进程释放内存时,可以通过合并相邻的空闲分区来优化内存空间的利用率。
1.遍历空闲分区链表,找到与释放的内存分区相邻的空闲分区。
2.将相邻的空闲分区进行合并,得到一个更大的空闲分区。
3.更新空闲分区链表。
首次适应算法的优点是简单有效,适用于动态内存分配的场景。
但是它也存在一些缺点,比如可能会造成内存碎片,不够高效地利用内存空间。
此外,首次适应算法相对于其他分配算法,如最佳适应算法和最坏适应算法,可能需要更多的时间来适合的空闲分区。
总结来说,首次适应算法是动态分区分配中常用的算法之一,其主要思想是按照分区链表的顺序第一个大小满足进程需求的空闲分区来分配内存。
虽然存在一些缺点,但在实际应用中,首次适应算法被广泛使用。
首次适应算法最佳适应算法
首次适应算法最佳适应算法姓名:学号:实验名称:进程调度模拟实验实验目的:了解动态分区存储管理方式中的数据结构和分配算法,加深对动态分区存储管理方式及其实现技术的理解。
实验内容:#include#includetypedefstructSpare{intSA;intsize;}spare;voidinit(spare*S,intcount){cout<for(inti=0;i{cin>>S[i].SA>>S[i].size;}}voidsort(spare *s,int count){spare min;for(inti=0;ifor(intj=i;jif(s[j].SA {min=s[j];s[j]=s[i];s[i]=min;}}voidFF(spare*s,int count){inti=1,Jsize,j=0; charc='Y'; cout<while(c=='Y') {cout<cin>>Jsize;for(j;j{if(s[j].size>=Jsize) {s[j].size-=Jsize; cout<<s[j].SA+=Jsize; break;}}if(j==count)cout< cout<cin>>c;i++;}}voidmain(){intcount;cout<cin>>count; spare*s;s=(spare*)malloc(count*sizeof(spare)); init(s,count);cout<FF(s,count);cout<sort(s,count);FF(s,count);}实验结果:。
首次适应算法
首次适应算法
首次适应算法是一种有效的机器学习算法,它旨在解决复杂的机器学习问题,其中包括模型预测、分类和聚类等。
它的基本原理是将输入数据映射到一个高维空间,以生成一组最优的参数,以便最终达到最佳的结果。
首次适应算法的特点是它有一个“学习率”,它决定了模型的收敛速度。
较高的学习率意味着模型会快速收敛,但是可能会导致收敛到局部最优解,因此学习率必须适当调整,以达到最佳的效果。
此外,首次适应算法还可以根据模型的表现调整参数,以便更快的收敛。
首次适应算法的应用场景非常广泛,可以用于多种机器学习任务,如模式识别、机器翻译、图像识别等。
它对模型的收敛更有利,并且可以调整参数,使模型更快的收敛,从而获得更好的效果。
总之,首次适应算法是一种有效的机器学习算法,它具有可调整学习率和自适应参数的特性,可用于多种机器学习任务,为机器学习任务带来更好的效果。
首次适应算法 实验报告
首次适应算法实验报告引言首次适应算法(First Fit)是一种内存分配算法,用于解决操作系统中的内存管理问题。
在该算法中,操作系统将可用的内存空间分为若干个大小不等的分区,当一个新的作业需要分配内存时,算法通过在空闲分区列表中查找第一个能够满足作业大小的分区,找到第一个合适的位置将作业分配到该分区。
本次实验旨在通过调试和运行一个模拟的内存管理系统,了解首次适应算法的实现原理,并比较它与其他内存分配算法的性能差异。
实验环境- 操作系统:Windows 10- 开发语言:C++实验步骤和结果分析1. 设计数据结构我们首先设计了一个表示内存分区的数据结构`Partition`,包括以下成员变量:- `start`:表示分区的起始地址- `size`:表示分区的大小- `allocated`:表示分区是否已经分配给作业然后,我们设计了一个表示内存管理系统的数据结构`Memory`,包括以下成员变量:- `partitions`:表示分区列表,使用一个动态数组存储所有分区- `size`:表示内存总大小2. 实现首次适应算法在内存管理系统的实现中,我们通过设计一个`allocate`方法来实现首次适应算法的分配过程。
该方法接受一个作业的大小作为参数,返回一个指向分配的分区的指针。
如果找不到合适的分区,则返回`nullptr`。
首次适应算法的实现原理如下:- 遍历所有的分区,查找第一个未分配且大小大于作业大小的分区。
- 如果找到合适的分区,则将分区的`allocated`属性设置为`true`,表示已分配,并返回该分区的指针。
- 如果没有找到合适的分区,则返回`nullptr`。
3. 测试并分析结果在测试阶段,我们通过运行一系列的分配和释放操作来模拟作业的动态运行过程。
为了更好地观察内存的分配情况,我们将内存分为等大小的分区,并以图表的方式显示。
通过对不同大小的作业进行分配和释放测试,我们得到了如下结果:![内存分配示意图](memory_allocation.png)从上图可以看出,首次适应算法根据作业的大小选择不同的分区进行分配,确保了尽可能多地利用内存空间。
首次适应与循环首次适应算法实现
⾸次适应与循环⾸次适应算法实现⼀、实验内容编程实现⾸次适应与循环⾸次适应算法。
⼆、实验要求1.任选⼀种⾼级语⾔实现;三、实验过程1、 设计思想⾸次适应算法(FF):将所有空闲分区按照地址递增的次序链接,在申请内存分配时,从链⾸开始查找,将满⾜需求的第⼀个空闲分区分配给作业。
循环⾸次适应算法(NF):将所有空闲分区按照地址递增的次序链接,在申请内存分配时,总是从上次找到的空闲分区的下⼀个空闲分区开始查找,将满⾜需求的第⼀个空闲分区分配给作业2、 数据结构public class FreeArea {private int address;//内存地址private int size;//空闲区⼤⼩public FreeArea() {}public FreeArea(int address, int size) {this.address = address;this.size = size;}public int getAddress() {return address;}public void setAddress(int address) {this.address = address;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}}4、运⾏结果:四、实验代码RR.Hpackage com.hu;import java.util.Scanner;public class MemoAlloc {public static void main(String[] args) {System.out.println("======⾸次适应算法======");FreeArea freeArea[]= init();FF(freeArea);System.out.println("=====循环⾸次适应算法=====");FreeArea freeArea1[]= init();NF(freeArea1);}public static void FF(FreeArea freeArea[]){//⾸次适应算法Scanner scanner = new Scanner(System.in);System.out.println("请输⼊要分配的内存⼤⼩:");int size = scanner.nextInt();for (int i =0;i<freeArea.length;i++){if (size<=freeArea[i].getSize()){//若分配内存⼤⼩⼩于空闲分区⼤⼩则分配成功System.out.println("分配内存成功");freeArea[i].setSize(freeArea[i].getSize()-size);//修改空闲分区⼤⼩break;}if (i== freeArea.length-1&&size>freeArea[i].getSize()) System.out.println("分配失败");}}public static void NF(FreeArea freeArea[]){//循环⾸次适应Scanner scanner = new Scanner(System.in);System.out.println("请输⼊要分配的内存⼤⼩:");int size = scanner.nextInt();boolean isWhile=true;int ProcessNum =0;int j=0;for (int i=ProcessNum;i< freeArea.length;i++,j++){if (size <= freeArea[i].getSize() ) {//若分配内存⼤⼩⼩于空闲分区⼤⼩则分配成功System.out.println("分配内存成功");freeArea[i].setSize(freeArea[i].getSize() - size);ProcessNum = j+1;//下⼀次查找时从本次找到的空闲分区的下⼀个分区开始找break;}else if (ProcessNum!=0 && i== freeArea.length-1&&size>freeArea[i].getSize()){ProcessNum=0;//若开始查找时不是从链⾸开始,最后⼀个空闲分区⼤⼩仍不能满⾜要求,则返回第⼀个空闲分区}else if(ProcessNum==0&&i== freeArea.length-1&&size>freeArea[i].getSize()){System.out.println("分配失败");//若开始查找时是从链⾸开始,最后⼀个空闲分区⼤⼩仍不能满⾜要求,则分配失败};}}public static FreeArea[] init(){//空闲区初始化并排序System.out.println("初始化空闲区并分配内存地址与⼤⼩");Scanner scanner = new Scanner(System.in);FreeArea[] freeAreas = new FreeArea[5];for (int i=0;i<freeAreas.length;i++){System.out.println("请输⼊内存地址与⼤⼩:");freeAreas[i] = new FreeArea(scanner.nextInt(),scanner.nextInt());}FreeArea t;for (int i = 0;i<freeAreas.length;i++){for (int j = 0;j<freeAreas.length-1;j++){if(freeAreas[j].getAddress()>freeAreas[j+1].getAddress()){t = freeAreas[j+1];freeAreas[j+1]=freeAreas[j];freeAreas[j]=t;}}}return freeAreas;}}五、实验总结通过本次实验我更加了解了循环⾸次适应与⾸次适应算法,⾸次适应算法优先利⽤低地址部分空闲分区,保留了⾼地址部分的⼤空闲区,缺点是低址部分不断被划分,会留下很多难以利⽤的⼩的外部碎⽚,每次都从低地址部分开始查会增加查找时的开销。
操作系统 首次最佳适应算法
学号专业姓名实验日期教师签字成绩实验报告【实验名称】采用可变式分区管理,使用首次获最佳适应算法实现内存分配与回收【实验目的与原理】1、理解首次获最佳适应算法的内涵,并熟练掌握该算法。
2、学会可变式分区管理的原理是即在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。
3、当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区没有时应将空闲区一分为二。
为了便于快速查找,要不断地对表格进行紧缩,即让“空表目”项留在表的后部。
4、当一个作业执行完成时,作业所占用的分区应归还给系统。
作业的释放区与空闲区的邻接分以下四种情况考虑:①释放区下邻(低地址邻接)空闲区;②释放区上邻(高地址邻接)空闲区③释放区上下都与空闲区邻接;④释放区与空闲区不邻接。
【实验内容】#include<stdio.h>#include<iostream>#include<string>using namespace std;const int MAXJOB=100;//定义表最大记录数typedef struct node{int front;int length;char data[20];}job;job frees[MAXJOB];//定义空闲区表int free_quantity;job occupys[MAXJOB];//定义已分配区表int occupy_quantity;//初始化函数void initial(){int i;for(i=0;i<MAXJOB;i++){frees[i].front=-1;frees[i].length=0;strcpy(frees[i].data,"free");occupys[i].front=-1;occupys[i].length=0;strcpy(occupys[i].data," ");}free_quantity=0;occupy_quantity=0;}//创建空闲分区表int creatfree(){FILE *fp;char fname[20];cout<<"请输入空闲区数据文件来源的文件名:"; cin>>fname;if((fp=fopen(fname,"r"))==NULL){cout<<"错误,文件打不开,请检查文件名"<<endl; }else{while(!feof(fp)){fscanf(fp,"%d\t%d\n",&frees[free_quanti ty].front,&frees[free_quantity].length);free_quantity++;}cout<<"空闲的分区表已建立!\n";return 1;}return 0;}void sort()//将free空间安首地址从小到大的顺序排列{int i,j,p;for(i=0;i<free_quantity-1;i++){p=i;for(j=i+1;j<free_quantity;j++){if(frees[j].front<frees[p].front){p=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}//显示函数void show(){int i;cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前空闲表:"<<endl;cout<<" 起始地址长度状态"<<endl;for(i=0;i<free_quantity;i++){cout.setf(2);cout.width(12);cout<<frees[i].front;cout.width(10);cout<<frees[i].length;cout.width(8);cout<<frees[i].data<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前已分配表:"<<endl;cout<<" 起始地址长度占用作业名"<<endl;for(i=0;i<occupy_quantity;i++){cout.setf(2);cout.width(12);cout<<occupys[i].front;cout.width(10);cout<<occupys[i].length;cout.width(8);cout<<occupys[i].data<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl;}//最先适应分配算法void assign(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length)//如果空闲空间I的长度〉作业长度{flag=1; //空闲标志位就置1 }}if(flag==0){cout<<endl<<"对不起,当前没有能满足你申请长度的空闲内存,请稍候再试!"<<endl;}else{t=0;i=0;while(t==0)//为空闲区间的时候{if(frees[i].length>=job_length){t=1;}i++;//如果空闲空间I的长度不大于作业长度,I加一,判断下一个空间}i--;occupys[occupy_quantity].front=frees[i] .front;strcpy(occupys[occupy_quantity].data,jo b_name);occupys[occupy_quantity].length=job_len gth;occupy_quantity++;if(frees[i].length>job_length)//如果空间的长度大于作业的长度,{frees[i].front+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}//撤消作业void cancel(){char job_name[20];int i,j,flag,p=0;int front;int length;cout<<"请输入要撤消的作业名:";cin>>job_name;flag=-1;for(i=0;i<occupy_quantity;i++){if(!strcmp(occupys[i].data,job_name))//当输入作业名匹配时{flag=i;front=occupys[i].front;length=occupys[i].length;}}if(flag==-1){cout<<"没有这个作业名"<<endl;}else{//加入空闲表for(i=0;i<free_quantity;i++){if((frees[i].front+frees[i].length)==fr ont)//上空{if(((i+1)<free_quantity)&&(frees[i+1].f ront==front+length))//下空{frees[i].length=frees[i].length+frees[i +1].length+length;for(j=i+1;j<free_quantity;j++){frees[j]=frees[j+1];}free_quantity--;p=1;}else{frees[i].length+=length;p=1;}}if(frees[i].front==(front+length))//下空上不空{frees[i].front=front;frees[i].length+=length;//第i 个空闲区间的长度=第i个空闲区间的长度+lengthp=1;}}if(p==0)//上下空闲区都不空{frees[free_quantity].front=front;frees[free_quantity].length=length;free_quantity++;}//删除分配表中的该作业for(i=flag;i<occupy_quantity;i++){occupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int flag=0;int t=1;int chioce=0;cout<<"*********** xxxxxxxxx***********\n"; initial();flag=creatfree();while(flag==1){sort();cout<<" 可变分区存储管理模拟系统"<<endl;cout<<" 1.申请空间 "<<endl;cout<<" 2.撤消作业 "<<endl;cout<<" 3.显示空闲表和分配表"<<endl;cout<<" 0.退出"<<endl;cout<<"请选择:";cin>>chioce;switch(chioce){case 1:assign();break;case 2:cancel();break;case 3:show();break;case 0:flag=0;break;default:cout<<"选择错误!"<<endl;}}}实验结果显示:【实验小结】本实验难度在两个方面,一是首次最佳适应算法assign(),这里我用的是结构体数组来存储空闲分区;二是对已分配分区的释放,这里同样采取结构体数组来存储已分配分区,用cancle()函数来实现。
首次适应算法
计算机操作系统实验一、实验名称:首次适应算法二、实验目的:熟悉并利用首次适应算法进行分配内存资源和回收资源。
三、设计思想:从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。
为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。
该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。
流程图(1)分配内存流程图(2)释放内存①当前作业为内存中最后一个作业②当前作业为倒数第二个作业③当前作业在链表中间四、主要数据结构:typedef struct memory{struct memory *former; //前向指针int waddress;//地址int wnum;//作业号int size;//分配内存大小int type;//状态0表示空闲1表示已分配struct memory *next; //后向指针}MEMORY;MEMORY *mem;五、运行结果截图分配内存释放内存附录1#include <iostream>#include <stdlib.h>#include <stdio.h>typedef struct memory{struct memory *former; //前向指针int waddress;//地址int wnum;//作业号int size;//分配内存大小int type;//状态0表示空闲1表示已分配struct memory *next; //后向指针}MEMORY;MEMORY *mem;void prfmem(MEMORY *ptr) //打印显示内存情况{MEMORY *temp;temp=ptr->next;printf("内存链的状态为:\n");while(temp!=NULL){if(temp->type==0){printf("内存空闲\n起始地址为:%d 空闲空间大小为:%d\n",temp->waddress,temp->size);}else{printf("内存已分配\n起始地址为%d 分配空间大小为%d 运行的作业号%d\n",temp->waddress,temp->size,temp->wnum);}temp=temp->next;}}void allocwork(MEMORY *ptr,MEMORY *assign)//根据算法分配内存{int sizemin;if(ptr->next==NULL)//内存没有作业运行{if(ptr->size>=assign->size){ptr->size=ptr->size-assign->size;assign->type=1;ptr->next=assign;assign->former=ptr;printf("作业%d申请%d的内存空间\n",assign->wnum,assign->size);}else{printf("没有足够的内存空间为作业%d分配\n",assign->wnum);delete assign;}}else //内存中如果已经分配了空间{MEMORY *previous,*current;previous=ptr;current=previous->next;while(current!=NULL){if(current->size>=assign->size&¤t->type==0){break;}previous=current;current=current->next;}if(current==NULL)//空闲链中没有为作业分配所需的空间,即释放的空闲区间小于要分配的作业空间{if(ptr->size>=assign->size){assign->waddress =640-(ptr->size);ptr->size=ptr->size-assign->size;assign->type=1;assign->former=previous;previous->next=assign;printf("作业%d申请%d的内存空间\n",assign->wnum,assign->size);}elseprintf("没有足够的内存空间为作业%d分配\n",assign->wnum);}else //释放的空闲链中有可为此作业分配的空间{if((current->size-assign->size)<=sizemin)//空闲链所具备的空间与作业所需空间大小差不多时{current->wnum=assign->wnum;current->type=1;delete assign;printf("作业%d申请%d的内存空间\n",assign->wnum,assign->size);}else{current->size=current->size-assign->size;assign->type=1;assign->waddress=current->waddress+current->size;if(current->next==NULL)//分配的空间是空闲链的最后一个元素{assign->former=current;current->next=assign;}else{assign->next=current->next;(current->next)->former=assign;assign->former=current;current->next=assign;}printf("作业%d申请%d的内存空间\n",assign->wnum,assign->size);}}}}void FF(int i)//依次初始化作业,对作业分配内存{int work[6];MEMORY *running;running=(MEMORY *)malloc(sizeof(MEMORY));printf("输入作业大小:\n");scanf("%d",&work[i]);if(running!=NULL){ running->former=NULL;running->waddress=0;running->wnum=i;running->size=work[i];running->type=0;running->next=NULL;allocwork(mem,running); prfmem(mem);}elseprintf("没有足够的内存空间\n");}void releasemem(MEMORY *ptr,int i)//释放内存{MEMORY *previous,*current;previous=ptr; current=previous->next;while(current!=NULL) //找到需要释放的作业位置{if(current->type==1&¤t->wnum==i){ break;}previous=current;current=current->next;}if(current==NULL){ printf("内存中没有找到需要释放的作业!\n"); return; }else if(current->next==NULL) //当前作业为内存中最后一个作业{if(previous->type==0) //与前一个相邻空闲区合并{previous->size=previous->size+current->size;previous->next=NULL;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else{current->type=0;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}}else if((current->next)->next==NULL)//当前作业为倒数第二个作业{if(previous->type==0&&(current->next)->type==0) //释放的地址空间前后均为空闲区{previous->size=previous->size+current->size+(current->next)->size;previous->next=NULL;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else if(previous->type==0) //前面有空闲块{previous->size=previous->size+current->size;(current->next)->former=previous;previous->next=current->next;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else if((current->next)->type==0)//后面有空闲块{current->size=current->size+(current->next)->size;current->type=0;current->next=NULL;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else //前后都没有空闲块{current->type=0;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}}else //当前作业在链表中间{if(previous->type==0&&(current->next)->type==0) //前后均为空闲区{previous->size=previous->size+current->size+(current->next)->size;((current->next)->next)->former=previous;previous->next=(current->next)->next;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else if(previous->type==0) //前面有空闲块则把它和前面的合并{previous->size=previous->size+current->size;(current->next)->former=previous;previous->next=current->next;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else if((current->next)->type==0) //释放的地址空间后面有空闲块{current->size=current->size+(current->next)->size;current->type=0;((current->next)->next)->former=current;current->next=(current->next)->next;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}else //前后都没有空闲块{current->type=0;printf("作业%d释放%d的空间\n",current->wnum,current->size);prfmem(mem);}}}void initmem() //初始化{int a,i,j;mem=new MEMORY;mem->size=640;mem->former=0;mem->next=0;printf("申请内存请输入1\n"); printf("释放内存请输入2\n");scanf("%d",&a);while(a==1||a==2){if(a==1){printf("输入申请内存的作业编号1-5\n");scanf("%d",&i);FF(i);}if(a==2){printf("输入释放内存的作业编号1-5\n");scanf("%d",&j);releasemem(mem,j);}printf("申请内存请输入1\n"); printf("释放内存请输入2\n"); printf("退出输入其他键\n");scanf("%d",&a);}}void main(){initmem();}。
首次适应算法和循环首次适应算法
首次适应算法和循环首次适应算法一、实验目的1、加深操作系统内存管理过程的理解2、掌握内存分配算法的基本应用二、实验要求1.在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选取一分区分配给该作业2.上机时独立完成编辑,调试程序。
三、实验任务请同学们用C/C++实现一个完整的(可变)动态分区管理器,包括分配,回收,分区碎片整理等。
希望同学们实现如下功能:n 初始化功能:内存状态设置为初始状态。
n 分配功能:要求至少使用两种算法,用户可以选择使用。
n 回收功能:n 空闲块的合并:即紧凑功能,用以消除碎片。
当做碎片整理时,需要跟踪分配的空间,修改其引用以保证引用的正确性。
n 显示当前内存的使用状态,可以使用表格或图形。
四、实验指导1.基本思想动态分区是指系统不预先划分固定分区,而是在装入程序的时候划分内存区域,使得为程序分配的分区大小恰好等于该程序的需求量,且分区的个数是动态的。
显然动态分区有较大的灵活性,较之固定分区能获得好的内存利用率。
2.数据结构动态分区管理可以用两种数据结构实现,一种是已分配区表和空闲区表,也就是用预先定义好的系统空间来存放空间分配信息。
另一种也是最常用的就是空闲链表,由于对分区的操作是动态的,所以很难估计数据结构所占用的空间,而且空闲区表会占用宝贵的系统空间,所以提出了空闲链表的概念。
其特点是用于管理分区的信息动态生成并和该分区在物理地址上相邻。
这样由于可以简单用两个空闲块之间的距离定位已分配空间,不仅节约了系统空间,而且不必维持已分配空间的信息。
本实验是要做一个模拟程序,来模拟动态分区算法的分配和回收过程,并不是真正的去分配和回收内存。
基本的模拟方法有两种:(1)、先从内存中申请一块存储区,对这块存储区进行模拟的分配和回收活动。
(2)、不申请存储区,自己定义一块虚拟的存储区,对这块存储区进行模拟的分配和回收活动,分配和回收仅仅是对数据结构的修改而已。
程序代码:#include<iostream>using namespace std;intFreePartition[100];//空闲分区块数组intFirstPartition[100];//首次适应算法数组intCycleFirstPartition[100];//循环首次适应算法数组intProcessNeed[100];//每个作业的大小intPartitionNum,ProcessNum;//分区块数,作业数//首次适应算法void First(){inti,j;charstr;for(i=0;i<PartitionNum;i++){FirstPartition[i]=FreePartition[i];}for(i=0;i<ProcessNum;i++)//找出第一块满足作业的分区for(j=0;j<PartitionNum;j++){if(ProcessNeed[i]>FirstPartition[j])continue;else{FirstPartition[j]-=ProcessNeed[i];//找到后把分区大小减去作业的大小?? ? ? ? ? ? ? ?str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl; break;}}cout<<endl;cout<<"分配之后剩余情况:"<<endl;?? ?for(i=0;i<PartitionNum;i++)cout<<FirstPartition[i]<<" ";cout<<endl<<endl;}//循环首次适应算法voidCycleFirst(){inti,j=1;charstr;for(i=0;i<PartitionNum;i++){CycleFirstPartition[i]=FreePartition[i]; }for(i=0;i<ProcessNum;i++)//for(j=0;j<PartitionNum;j++){j=j-1;while(j<PartitionNum){if(ProcessNeed[i]>CycleFirstPartition[j])//continue;j++;else{CycleFirstPartition[j]-=ProcessNeed[i];str='A'+i;cout<<"作业"<<str<<"在第"<<j+1<<"块分区中"<<endl; break;}//j++;//cout<<j<<" ";if(j==PartitionNum&&i!=ProcessNum){i=-1;}}}cout<<endl;cout<<"分配之后剩余情况:"<<endl;for(i=0;i<PartitionNum;i++)cout<<CycleFirstPartition[i]<<" ";cout<<endl<<endl;}void main(){inti;cout<<"输入分区块数:"<<endl;cin>>PartitionNum;cout<<"输入每个分区的大小:"<<endl;for(i=0;i<PartitionNum;i++)cin>>FreePartition[i];cout<<"输入作业数:"<<endl;cin>>ProcessNum;cout<<"输入每个作业的大小:"<<endl;for(i=0;i<ProcessNum;i++)cin>>ProcessNeed[i];cout<<"------------首次适应算法-----------------"<<endl;First();cout<<"------------循环首次适应算法-------------"<<endl;?? ?CycleFirst();六、实验总结在一开始老师布置这次的实验题目时,自己根本不知道要干什么,因为在上课时对动态分区分配这节内容不是太了解,所以在上机时不知道如何下手,后来,将本章内容反复的看了几遍之后,终于有了自己的思路。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
fqlist[i].end=fqlist[i+1].end;
fqlist[i].capactity=fqlist[i].capactity+fqlist[i+1].capactity;
fqlist[i].flag=fqlist[i+1].flag;
for(int j=i+1;j<number-1;j++)
{
fqlist[j]=fqlist[j+1];
}
i=number;
flag++;
}
else{
fqlist[i].end=fqlist[i+1].end;
fqlist[i].capactity=fqlist[i].capactity+fqlist[i+1].capactity;
fqlist[i].flag=fqlist[i+1].flag;
实 验 报 告
系别
班级
学 号
姓 名
时间
地点
计算机科学系
计科1201
2014/12/29
机房 c105
课程名称
计算机操作系统
实验名称
内存管理
实 验 过 程
一.实验目的
1.了解内存管理的功能;
2.掌握进程可变内存管理的几种内存分配与回收算法;
3.掌握可变分区算法中空闲分区的合并方法;
二.实验内容
实现首次适应算法;
for(int j=i+1;j<number-1;j++)
{
fqlist[j]=fqlist[j+1];
}
}
}
}பைடு நூலகம்
}
flag++;
}
return 0;
}
ame,fqlist[i].start,fqlist[i].end,fqlist[i].capactity);
if(fqlist[i].flag==1){
printf("已使用\n");
count++;
}
else if(fqlist[i].flag==3){
printf("尾部\n");
count++;
}else if(fqlist[i].flag==2){
printf("未使用\n");
}else if(fqlist[i].flag==0){
printf("未使用\n");
scanf("%d",&neicun);
printf("内存大小neicun=%d\n",neicun);
fqlist[0].capactity=neicun;
fqlist[0].start=0;
fqlist[0].end=neicun-1;
fqlist[0].flag=3;lag!=1){apactity>size)ame='n';
fqlist[i].start=sum;
fqlist[i].end=sum+size-1;
fqlist[i].capactity=size;
fqlist[i].flag=1;
fqNum++;apactity;
}
}else{apactity;
}
}
if(flag==1)
printf("已为进程%c分配内存区!\n",jname);
}
}
return 0;
}
...\n");
exit(0);
return 0;
}
//主函数
int main(){
init_neicun();//初始化内存大小
menu();
return 0;
}
四.运行截图
五.实验总结
算法要求空闲链已地址递增的次序连接。分配内存时,从链首开始顺序查找,直到找到第一个满足要求的空间并分配给进程,把分配后余下的空间仍然留在链表中。若从链首至链尾都不满足要求,则分配失败。该算法倾向于优先使用低地址的空间,在不断分割中会产生很多空间碎片,并且每次都是从链首开始查找,这无疑增加了开销。
fqlist[i+1].start=sum+size;
fqlist[i+1].end=fqlist[i].end;
fqlist[i+1].capactity=fqlist[i].capactity-size;
fqlist[i+1].flag=fqlist[i].flag;
}
fqlist[i].name=jname;
else
printf("为进程%c分配内存区失败!\n",jname);
return 0;
}
ame==jname){
fqlist[i].name='n';
fqlist[i].flag=2;lag==0||fqlist[i].flag==2){
if(fqlist[i+1].flag!=1){
if(fqlist[i+1].flag==3)
三.实验程序
#include <>
#include <>
#include <iostream>
#define number 100ame='n';
fqlist[i].start=0;
fqlist[i].end=0;
fqlist[i].capactity=0;
fqlist[i].flag=0;
}
printf("请输入内存大小:");