操作系统实验四报告-主存空间分配和回收(含源码)
- 格式:doc
- 大小:543.00 KB
- 文档页数:27
漳州师范学院实验报告班级 11网络2班学号姓名座号 15 同组人实验日期成绩课程名称:操作系统实验题目:主存储器空间的分配和回收实验目的与要求PC 兼容机。
Window xp 以上操作系统实验环境的配置第 1 页实验内容与具体步骤实验内容与具体步骤源代码如下:#include <stdio.h>#include <stdlib.h>#include <iostream.h>#define n 10 //模拟实验中,允许的最大作业数目#define m 10 //模拟实验中,允许的最大空间分区数目#define minisize 100 /*该空闲区低于该值,可视为碎片。
分配分区时,若寻找到的最小适合空间相对作业请求的空间来说仍大于该数值,则要分割该分区,但是分割后,空闲为很小,变成碎片,则不分割。
*/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 job,float xk){ //该内存分配算法,采用是最优适应算法,int i,k; float ad; k=-1;for(i=0;i<=m;i++)if(free_table[i].length>=xk&&free_table[i].flag==1)//通过该循环,先找到最小分区if(k==-1||free_table[i].length<free_table[k].length)k=i;//用变量k来存放最小的分区的下标if(k==-1){ printf("Allocation failure!\n");return;}if(free_table[k].length-xk<=minisize){//不需分割的情况,用变量ad和xk存放将分配出去空闲区的地址和长度free_table[k].flag=0;ad=free_table[k].address;xk=free_table[k].length;}else{//若寻找到的最小适合空间相对作业请求的空间来说仍过大,则进行分割分区。
实验四操作系统存储管理实验报告一、实验目的本次操作系统存储管理实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配、回收、地址转换等关键技术,提高对操作系统存储管理机制的认识和应用能力。
二、实验环境操作系统:Windows 10开发工具:Visual Studio 2019三、实验原理1、内存分配方式连续分配:分为单一连续分配和分区式分配(固定分区和动态分区)。
离散分配:分页存储管理、分段存储管理、段页式存储管理。
2、内存回收算法首次适应算法:从内存低地址开始查找,找到第一个满足要求的空闲分区进行分配。
最佳适应算法:选择大小最接近作业需求的空闲分区进行分配。
最坏适应算法:选择最大的空闲分区进行分配。
3、地址转换逻辑地址到物理地址的转换:在分页存储管理中,通过页表实现;在分段存储管理中,通过段表实现。
四、实验内容及步骤1、连续内存分配实验设计一个简单的内存分配程序,模拟固定分区和动态分区两种分配方式。
输入作业的大小和请求分配的分区类型,程序输出分配的结果(成功或失败)以及分配后的内存状态。
2、内存回收实验在上述连续内存分配实验的基础上,添加内存回收功能。
输入要回收的作业号,程序执行回收操作,并输出回收后的内存状态。
3、离散内存分配实验实现分页存储管理的地址转换功能。
输入逻辑地址,程序计算并输出对应的物理地址。
4、存储管理算法比较实验分别使用首次适应算法、最佳适应算法和最坏适应算法进行内存分配和回收操作。
记录不同算法在不同作业序列下的内存利用率和分配时间,比较它们的性能。
五、实验结果与分析1、连续内存分配实验结果固定分区分配方式:在固定分区大小的情况下,对于作业大小小于或等于分区大小的请求能够成功分配,否则分配失败。
内存状态显示清晰,分区的使用和空闲情况一目了然。
动态分区分配方式:能够根据作业的大小动态地分配内存,但容易产生内存碎片。
2、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。
存储管理动态分区分配及回收算法课程名称:计算机操作系统班级:信1501-2实验者姓名:李琛实验日期:2018年5月20日评分:教师签名:一、实验目的分区管理是应用较广泛的一种存储管理技术。
本实验要求用一种结构化高级语言构造分区描述器,编制动态分区分配算法和回收算法模拟程序,并讨论不同分配算法的特点.二、实验要求1、编写:First Fit Algorithm2、编写:Best Fit Algorithm3、编写:空闲区回收算法三、实验过程(一)主程序1、定义分区描述器node,包括3 个元素:(1)adr——分区首地址(2)size-—分区大小(3)next——指向下一个分区的指针2、定义3 个指向node 结构的指针变量:(1)head1—-空闲区队列首指针(2)back1-—指向释放区node 结构的指针(3)assign——指向申请的内存分区node 结构的指针3、定义1 个整形变量:free——用户申请存储区的大小(由用户键入)(二)过程1、定义check 过程,用于检查指定的释放块(由用户键入)的合法性2、定义assignment1 过程,实现First Fit Algorithm3、定义assignment2 过程,实现Best Fit Algorithm4、定义acceptment1 过程,实现First Fit Algorithm 的回收算法5、定义acceptment2 过程,实现Best Fit Algorithm 的回收算法6、定义print 过程,打印空闲区队列(三)执行程序首先申请一整块空闲区,其首址为0,大小为32767;然后,提示用户使用哪种分配算法,再提示是分配还是回收;分配时要求输入申请区的大小,回收时要求输入释放区的首址和大小。
实验代码Main。
cpp#include〈stdio。
h〉#include<stdlib。
h〉#include<string。
主存空间的分配与回收#include"stdio.h"#include"stdlib.h"#define n 10 /*假定系统允许的最大作业为n,假定模拟实验中n 值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/#define minisize 100struct{float address;float length; /*已分分区长度,单位为字节*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/}used_table[n]; /*已分配区表*/struct{float address; /*空闲区起始地址*/float length; /*空闲区长度,单位为字节*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配*/}free_table[m];void main( ){int i,a;void allocate(char str,float leg);//分配主存空间函数void reclaim(char str);//回收主存函数float xk;char J;/*空闲分区表初始化:*/free_table[0].address=10240;free_table[0].length=102400;free_table[0].flag=1;for(i=1;i<m;i++)free_table[i].flag=0;/*已分配表初始化:*/for(i=0;i<n;i++)used_table[i].flag=0;while(1){printf("\n选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)\n");printf("选择功项(0~3) :");scanf("%d",&a);switch(a){case 0: exit(0); /*a=0程序结束*/case 1: /*a=1分配主存空间*/printf("输入作业名J和作业所需长度xk: ");scanf("%*c%c%f",&J,&xk);allocate(J,xk);/*分配主存空间*/break;case 2: /*a=2回收主存空间*/printf("输入要回收分区的作业名");scanf("%*c%c",&J);reclaim(J);/*回收主存空间*/break;case 3: /*a=3显示主存情况*//*输出空闲区表和已分配表的内容*/printf("输出空闲区表:\n起始地址分区长度标志\n");for(i=0;i<m;i++)printf("%6.0f%9.0f%6d\n",free_table[i].address,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("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].lengt h, used_table[i].flag);elseprintf("%6.0f%9.0f%6d\n",used_table[i].address,used_table[i].lengt h, used_table[i].flag);break;default:printf("没有该选项\n");}/*case*/}/*while*/}/*主函数结束*/int uflag;//分配表标志int fflag;//空闲表标志float uend_address;float fend_address;void allocate(char str,float leg){uflag=0;fflag=0;int k,i;float ressize;for(i=0;i<m;i++){if(free_table[i].flag==1 && free_table[i].length>=leg) {fflag=1;break;}}if(fflag==0)printf("没有满足条件的空闲区\n");else{ressize=free_table[i].length-leg;for(k=0;k<n;k++){if(used_table[k].flag==0){if(ressize<minisize)//剩余块过小{used_table[k].length=free_table[i].length;used_table[k].address=free_table[i].address;used_table[k].flag=str;free_table[i].length=0;free_table[i].flag=0;break;}else{used_table[k].address=free_table[i].address+ressize;used_table[k].flag=str;used_table[k].length=leg;free_table[i].length=ressize;break;}}}//for结束}}void reclaim(char str){uflag=0;fflag=0;int k,i;for(k=0;k<n;k++){if(used_table[k].flag==str){uflag=1;break;}}if(uflag==0)printf("\n找不到该作业!\n");else{for(i=0;i<m;i++){uend_address=used_table[k].address+used_table[k].length; fend_address=free_table[i].address+free_table[i].length;if(used_table[k].address==fend_address)//上邻{fflag=1;free_table[i].length=free_table[i].length+used_table[k].length;free_table[i].flag=1;used_table[k].flag=0;used_table[k].length=0;used_table[k].address=0;printf("\n已回收!\n");break;}else{if(free_table[i].address==uend_address)//下邻{fflag=1;free_table[i].address=used_table[k].address;free_table[i].length=free_table[i].length+used_table[k].length;free_table[i].flag=1;used_table[k].flag=0;used_table[k].length=0;used_table[k].address=0;printf("\n已回收!\n");break;}}}//for结束if(fflag==0){i=0;for(i=0;i<m;i++){if(free_table[i].flag==0){free_table[i].address=used_table[k].address;free_table[i].length=used_table[k].length;free_table[i].flag=1;used_table[k].length=0;used_table[k].flag=0;used_table[k].address=0;break;}}printf("\n已回收!\n");}}}11。
主存储器空间的分配和回收直接进行源代码的编写:/*作业名用1,2,3,···表示*/#include<iostream>#include<list>using namespace std;#define TOTLE_LEFT 108 //除系统占用内存外的剩余内存#define first_free 14 //第一块空闲区的起始地址#define first_size 12 //第一块空闲区的大小#define sec_free 32 //第二块空闲区的起始地址#define sec_size 96 //第二块空闲区的大小#define first_job_size 3#define sec_job_size 23#define third_job_size 3//空闲分区表结点struct Free{int start;int length;Free(int s,int l);};Free::Free(int s,int l){start = s;length = 1;}//已分配分区表结点struct Task{int name;int start;int length;Task(int n,int s,int l); };Task::Task(int n,int s,int l) {name = n;start = s;length = l;}//声明空闲分区表list<Free*>free_list;list<Task*>Task_list;//分配可用的起始地址int get_free(int size){int start = -1;//查找适当的空闲分区list<Free*>::iterator it = free_list.begin();bool find = false;while(it!=free_list.end()){if((*it)->length>=size){find = true;start = (*it)->start;//大于,就分割,把低地址分配出去if((*it)->length>size){(*it)->start += size;(*it)->length -= size;}//等于,就从空闲区中删除elsefree_list.erase(it);break; //找到就跳出循环}it ++;}return start;}void do_request(int name,int size){if(name==0){cout<<”申请不合法!非法的作业名!”<<endl;return;}if(size>TOTLE_LEFT){cout<<”申请不合法!超出了最大可用内存!”<<endl;return;}//查找是否已存在同名作业bool find = false;list<Task*>::iterator it = task_list.begin();while(it!=task_list.end()){if((*it)->name ==name){find = true;break;}it++;}if(find){cout<<”此作业已存在!”<<endl;return;}//从空闲分区选择合适的空间int start = get_free(size);//未找到合适空间if(start ==-1){cout<<”系统内存不足!作业等待!”<<endl;return;}Task * ta = new Task(name,start,size);task_list.push_back(ta);cout<<”作业申请内存成功!”<<endl;}//插入到空闲分区表,起始地址从小到大void free_task(int start,int length){//查找要插入的位置list<Free*>::iterator init_it,last_it;last_it = init_it;list<Free*>::iterator it = free_list.begin();while(it! = free_list.end()){if((*it)->start>start) break;last_it = it;it ++;}bool link_prev = false;bool link_next = false;//有前一个小时if(last_it! = init_it){if((*last_it)->start+(*last_it)->length == start) link_prev = true;}//有后一个小时if(it! = free_list.end()){if(start + length ==(*it)->start)link_next = true;}//与前后都相连if(link_prev&&link_next){(*last_it)->length += length + (*it) ->length;free_list.erase(it);}//只与前相连else if(link_prev){(*last_it)->length += length;//只与后相连else if(link_next){(*it)->start = start;(*it)->length += length;}//前后都不相连else{Free *fr = new Free(start,length);Free_list.insert(it,fr);}}void do_revoke(int name){if(name ==0){cout<<”错误!不能回收系统内存!”<<endl;return;}//查找要回收的作业是否存在bool find = false;list<Task*>::iterator it = task_list.begin();while(it! = task_list,end()){if((*it)->name == name){find = true;break;}it ++;}if(!find){cout<<”错误!要回收的作业不存在!”<<endl;return;}free_task((*it)->start,(*it)->length);task_list.erase(it);cout<<”回收作业占用内存成功!”<<endl;}void print_task(){cout<<”作业名称起始地址大小”<<endl;for(list<Task*>::iterator it = task_list.begin();it!=task_list.end();it++){cout<<(*it)->name<<””<<(*it)->start<<””<<(*it)->length<<endl;}}void print_free(){cout<<”以下是空闲分区表的状态”<<endl;<<”起始地址大小”<<endl;for(list<Free*>::iterator it = free_list.begin();it! = free_list.end();it ++){cout<<(*it)->st art<<””<<(*it)->length<<endl;}}int main(0{//把系统占用后剩余的内存空间计入空闲分区表Free *fr1 = new Free(first_free,first_size);free_list.push_back(fr1);Free *fr = new Free(sec_free,sec_size);free_list.push_back(fr);Task *ta = new Task(1,26,first_job_size);task_list.push_back(ta);Task *ta1 = new Task(3,29,third_job_size);task_list.push_back(ta1);Task *ta2 = new Task(2,128,sec_job_size);task_list.push_back(ta2);print_free():bool quit = false;while(!quit){cout<<”选择要进行的操作:1.申请内存2.回收内存3.查看作业”;int op;cin>>op;if(op==1){int name;int size;cout<<”请输入作业名及占用空间大小:”;cin>>name;cin>>size;do_request(name,size);print_free();}else if(op==2){ int name;cout<<”请输入要回收的作业名:”;cin>>name;do_revoke(name);print_free();}else if(op==3){print_task();}else{cout<<”非法操作!”<<endl;}cout<<”***********************”<<endl; char con;cout<<继续(y/n):”;cin>>con;if(con ==’n’||con == ‘N’){quit = true;}}return 0 ;}。
实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。
二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。
三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。
在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。
2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。
为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。
3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。
同样通过对空闲分区链表的排序和查找来实现。
(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。
在模拟过程中,使用一个队列来记录页面的进入顺序。
2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。
通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。
3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。
四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。
2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。
3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。
#include<stdio.h>#include<stdlib.h>#define NUM 128typedef struct{ int zm_no;int cd_no;int jl_no;}disk;void disp(int m[]){int i;printf("位?示º?图ª?:êo\n");for(i=0;i<NUM;i++){if(i%8==0)printf("\n");printf("%d\t",m[i]);}printf("\n");}void creat(int m[]){ int j=0,zh,wh;int keyong=0;while(j<NUM){ if(m[j]==0){ keyong=1;m[j]=1;disk a;a.zm_no=j/8;a.cd_no=(j%8)/4;a.jl_no=(j%8)%4;zh=a.zm_no;wh=a.cd_no*4+a.jl_no;printf("柱¨´面?号?\t磁ä?道̨¤号?\t物?理¤¨ª记?录?号?\n");printf("%d\t%d\t%d\n",a.zm_no,a.cd_no,a.jl_no);printf("字Á?号?\t位?号?\n");printf("%d\t%d\n",zh,wh);break;}else j++;}if(keyong==0){ printf("无T可¨¦用®?磁ä?盘¨¬块¨¦!ê?\n");printf("\n");}}void del(int m[]){ disk b;int zm_no,cd_no,jl_no,j;printf("输º?入¨?待äy回?收º?磁ä?盘¨¬块¨¦的Ì?柱¨´面?号?,ê?磁ä?道̨¤号?,ê?物?理¤¨ª记?录?号?:êo");scanf("%d%d%d",&b.zm_no,&b.cd_no,&b.jl_no);j=8*b.zm_no+4*b.cd_no+b.jl_no;if(m[j]==0)printf("已°?是º?空?闲D状Á¡ä态¬?,ê?不?必À?回?收º?!ê?\n");else{ m[j]=0;disp(m);}}int main(){int i;int input=1;int m[NUM]={ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};while(input!=0){ printf("1.当Ì¡À前¡ã磁ä?盘¨¬状Á¡ä态¬? 2.申¦¨º请?磁ä?盘¨¬块¨¦ 3.回?收º?磁ä?盘¨¬块¨¦ 0.退ª?出?\n");scanf("%d",&input);switch(input){ case 1: disp(m);break;case 2: creat(m);break;case 3: del(m);break;default:break;}}system("pause");return 0;}。
存储管理动态分区分配及回收算法课程名称:计算机操作系统班级:信1501-2实验者姓名:李琛实验日期:2018年5月20日评分: 教师签名:一、实验目的分区管理就是应用较广泛的一种存储管理技术。
本实验要求用一种结构化高级语言构造分区描述器,编制动态分区分配算法与回收算法模拟程序,并讨论不同分配算法的特点。
二、实验要求1、编写:First Fit Algorithm2、编写:Best Fit Algorithm3、编写:空闲区回收算法三、实验过程(一)主程序1、定义分区描述器node,包括3 个元素:(1)adr——分区首地址(2)size——分区大小(3)next——指向下一个分区的指针2、定义3 个指向node 结构的指针变量:(1)head1——空闲区队列首指针(2)back1——指向释放区node 结构的指针(3)assign——指向申请的内存分区node 结构的指针3、定义1 个整形变量:free——用户申请存储区的大小(由用户键入)(二)过程1、定义check 过程,用于检查指定的释放块(由用户键入)的合法性2、定义assignment1 过程,实现First Fit Algorithm3、定义assignment2 过程,实现Best Fit Algorithm4、定义acceptment1 过程,实现First Fit Algorithm 的回收算法5、定义acceptment2 过程,实现Best Fit Algorithm 的回收算法6、定义print 过程,打印空闲区队列(三)执行程序首先申请一整块空闲区,其首址为0,大小为32767;然后,提示用户使用哪种分配算法,再提示就是分配还就是回收;分配时要求输入申请区的大小,回收时要求输入释放区的首址与大小。
实验代码Main、cpp#include<stdio、h>#include<stdlib、h>#include<string、h>#include<iostream>using namespace std;#define MAX_SIZE 32767typedef struct node{int id;int adr;int size;struct node *next;}Node;Node *head1, *head2, *back1, *back2, *assign;int request;int check(int add, int siz, char c){Node *p, *head;int check = 1;if (add<0 || siz<0)check = 0;/*地址与大小不能为负*/if (c == 'f' || c == 'F')head = head1;elsehead = head2;p = head->next;while ((p != NULL) && check)if (((add<p->adr) && (add + siz>p->adr)) || ((add >= p->adr) && (add<p->adr + p->size))) check = 0;elsep = p->next;if (check == 0)printf("\t输入释放区地址或大小有错误!!!\n");return check;}void init(){Node *p;head1 = (Node*)malloc(sizeof(Node));head2 = (Node*)malloc(sizeof(Node));p = (Node*)malloc(sizeof(Node));head1->next = p;head2->next = p;p->size = MAX_SIZE;p->adr = 0;p->next = NULL;p->id = 0;}Node* assignment1(int num, int req){Node *before, *after, *ass;ass = (Node*)malloc(sizeof(Node));before = head1;after = head1->next;ass->id = num;ass->size = req;while (after->size<req){before = before->next;after = after->next;}if (after == NULL){ass->adr = -1;}else{if (after->size == req){before->next = after->next;ass->adr = after->adr;}else{after->size -= req;ass->adr = after->adr;after->adr += req;}}return ass;}void acceptment1(int address, int siz, int rd) {Node *before, *after;int insert = 0;back1 = (Node*)malloc(sizeof(Node));before = head1;after = head1->next;back1->adr = address;back1->size = siz;back1->id = rd;back1->next = NULL;while (!insert&&after){//将要被回收的分区插入空闲区(按首址大小从小到大插入)if ((after == NULL) || ((back1->adr <= after->adr) && (back1->adr >= before->adr))){before->next = back1;back1->next = after;insert = 1;}else{before = before->next;after = after->next;}}if (insert){if (back1->adr == before->adr + before->size){//与前边分区合并before->size += back1->size;before->next = back1->next;free(back1);}else if (after&&back1->adr + back1->size == after->adr){//与后边分区合并back1->size += after->size;back1->next = after->next;back1->id = after->id;free(after);after = back1;}printf("\t首先分配算法回收内存成功!\n");}elseprintf("\t首先分配算法回收内存失败!\n");}Node* assignment2(int num, int req){Node *before, *after, *ass, *q;ass = (Node*)malloc(sizeof(Node));q = (Node*)malloc(sizeof(Node));before = head2;after = head2->next;ass->id = num;ass->size = req;while (after->size<req){before = before->next;after = after->next;}if (after == NULL){ass->adr = -1;}else{if (after->size == req){before->next = after->next;ass->adr = after->adr;}else{q = after;before->next = after->next;ass->adr = q->adr;q->size -= req;q->adr += req;before = head2;after = head2->next;if (after == NULL){before->next = q;q->next = NULL;}else{while ((after->size)<(q->size)){before = before->next;after = after->next;}before->next = q;q->next = after;}}}return (ass);}void acceptment2(int address, int siz, int rd){Node *before, *after;int insert = 0;back2 = (Node*)malloc(sizeof(Node));before = head2;after = head2->next;back2->adr = address;back2->size = siz;back2->id = rd;back2->next = NULL;if (head2->next == NULL){//空闲队列为空head2->next = back2;head2->size = back2->size;}else{//空闲队列不为空while (after){if (back2->adr == after->adr + after->size){//与前边空闲分区合并before->next = after->next;after->size += back2->size;back2 = after;}else{before = before->next;after = after->next;}}before = head2;after = head2->next;while (after){if (after->adr == back2->adr + back2->size){//与后边空闲区合并before->next = after->next;back2->size += after->size;}else{before = before->next;after = after->next;}}before = head2;after = head2->next;while (!insert){//将被回收的块插入到恰当的位置(按分区大小从小到大)if (after == NULL || ((after->size>back2->size) && (before->size<back2->size))){before->next = back2;back2->next = after;insert = 1;break;}else{before = before->next;after = after->next;}}}if (insert)printf("\t最佳适应算法回收内存成功!\n");elseprintf("\t最佳适应算法回收内存失败!!\n");}void print(char choice)//输出空闲区队列信息{Node *p;if (choice == 'f' || choice == 'F')p = head1->next;elsep = head2->next;if (p){printf("\n空闲区队列的情况为:\n");printf("\t编号\t首址\t终址\t大小\n");while (p){printf("\t%d\t%d\t%d\t%d\n", p->id, p->adr, p->adr + p->size - 1, p->size);p = p->next;}}}void menu()//菜单及主要过程{char chose;int ch, num=0, r, add, rd;while (1){system("cls");printf("-------存储管理动态分区分配及回收算法-------\n");printf(" F 最先适应算法\n");printf(" B 最佳适应算法\n");printf(" E 退出程序\n");printf("----------------------------------------------\n");printf("请选择算法:");cin >> chose;//scanf("%c", &chose);if (chose == 'e' || chose == 'E')exit(0);else{system("cls");while (1){if (chose == 'f' || chose == 'F')printf("最先适应算法:\n");if (chose == 'b' || chose == 'B')printf("最佳适应算法:\n");printf("----------------------------------------------\n");printf(" 1 分配内存\n");printf(" 2 回收内存\n");printf(" 3 查瞧内存\n");printf(" 4 返回\n");printf("----------------------------------------------\n\n");printf("请选择:");scanf("%d", &ch);fflush(stdin);switch (ch){case 1:printf("输入申请的分区大小:"); scanf("%d", &r);if (chose == 'f' || chose == 'F')assign = assignment1(num, r);elseassign = assignment2(num, r);if (assign->adr == -1){printf("分配内存失败!\n");}elseprintf("分配成功!分配的内存的首址为:%d\n", assign->adr);break;case 2:printf("输入释放的内存的首址:"); scanf("%d", &add);printf("输入释放的内存的大小:"); scanf("%d", &r);printf("输入释放的内存的编号:"); scanf("%d", &rd);if (check(add, r, chose)){if (chose == 'f' || chose == 'F')acceptment1(add, r, rd);elseacceptment2(add, r, rd);}break;case 3:print(chose); break;case 4:menu(); break;}}}}}void main()//主函数{init();menu();}四、实验结果操作系统存储管理动态分区分配及回收算法附源码五、实验总结通过这次实验我练习了存储管理动态分区分配及回收算法,对操作系统中动态可变分区存储管理有了更深刻的了解。
操作系统实验四报告-主存空间分配和回收(含源码)计算机学院计算机科学与技术专业班学号姓名教师评定_________________实验题目主存空间的分配和回收一、实验目的熟悉主存的分配与回收。
理解在不同的存储管理方式下,如何实现主存空间的分配与回收。
掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。
二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。
所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。
可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。
同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。
同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。
三、实验主要仪器设备和材料实验环境硬件环境: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运行完毕,释放所占内存。
主存空间的分配与回收实验报告附录:源代码#include<stdio.h>#include<stdlib.h>#define OK 1 //完成#define ERROR 0 //出错typedef int Status;typedef struct free_table//定义一个空闲区说明表结构{int num; //分区序号long address; //起始地址long length; //分区大小int state; //分区状态}ElemType;typedef struct Node// 线性表的双向链表存储结构{ElemType data;struct Node *prior; //前趋指针struct Node *next; //后继指针}Node,*LinkList;LinkList first; //头结点LinkList end; //尾结点int flag;//记录要删除的分区序号Status Initblock()//开创带头结点的内存空间链表{first=(LinkList)malloc(sizeof(Node)); end=(LinkList)malloc(sizeof(Node)); first->prior=NULL;first->next=end;end->prior=first;end->next=NULL;end->data.num=1;end->data.address=40;end->data.length=600;end->data.state=0;return OK;}void sort()//分区序号重新排序{Node *p=first->next,*q;q=p->next;for(;p!=NULL;p=p->next){f or(q=p->next;q;q=q->next){if(p->data.num>=q->data.num){q->data.num+=1;}}}}//显示主存分配情况void show(){ int flag=0;//用来记录分区序号Node *p=first;p->data.num=0;p->data.address=0;p->data.length=40;p->data.state=1;sort();printf("\n\t\t》主存空间分配情况《\n");printf("********************************** ************************\n\n");printf("分区序号\t起始地址\t分区大小\t分区状态\n\n");while(p){printf("%d\t\t%d\t\t%d",p->data.num,p->data. address,p->data.length);if(p->data.state==0) printf("\t\t空闲\n\n");else printf("\t\t已分配\n\n");p=p->next;}printf("********************************** ************************\n\n");}//首次适应算法Status First_fit(int request){//为申请作业开辟新空间且初始化Node *p=first->next;LinkListtemp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p){if((p->data.state==0)&&(p->data.length==reque st)){//有大小恰好合适的空闲块p->data.state=1;return OK;break;}else if((p->data.state==0) && (p->data.length>request)){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;temp->data.num=p->data.num;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->da ta.length;p->data.length-=request;p->data.num+=1;return OK;break;}p=p->next;}return ERROR;}//最佳适应算法Status Best_fit(int request){int ch; //记录最小剩余空间Node *p=first;Node *q=NULL; //记录最佳插入位置LinkListtemp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最小空间和最佳位置{if((p->data.state==0) && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length > p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.state=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//最差适应算法Status Worst_fit(int request){int ch; //记录最大剩余空间Node *p=first->next;Node *q=NULL; //记录最佳插入位置LinkListtemp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最大空间和最佳位置{if(p->data.state==0 && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length <p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.length=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//分配主存Status allocation(int a){int request;//申请内存大小printf("请输入申请分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("分配大小不合适,请重试!");return ERROR;}switch(a)case 1: //默认首次适应算法if(First_fit(request)==OK)printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 2: //选择最佳适应算法if(Best_fit(request)==OK)printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 3: //选择最差适应算法if(Worst_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;}Status deal1(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.s tate!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.stat e==0){q->data.length+=q->next->data.length;q->next=q->next->next;q->next->next->prior=q;q->data.state=0;q->data.num=flag;}if(q->prior->data.state==0&&q->next->data.sta te==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}Status deal2(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.s tate!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=p->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.stat e==0){q->data.state=0;}if(q->prior->data.state==0&&q->next->data.sta te==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.stat e!=0){q->data.state=0;}}}return OK;}//主存回收Status recovery(int flag){Node *p=first;for(;p!=NULL;p=p->next){if(p->data.num==flag){if(p->prior==first){if(p->next!=end)//当前P指向的下一个不是最后一个时{if(p->next->data.state==0) //与后面的空闲块相连{p->data.length+=p->next->data.length;p->next->next->prior=p;p->next=p->next->next;p->data.state=0;p->data.num=flag;}else p->data.state=0;}if(p->next==end)//当前P指向的下一个是最后一个时{p->data.state=0;}}//结束if(p->prior==block_first)的情况else if(p->prior!=first){if(p->next!=end){deal1(p);}else{deal2(p);}}//结束if(p->prior!=block_first)的情况}//结束if(p->data.num==flag)的情况}printf("\t****回收成功****");return OK;}//主函数void main(){int i; //操作选择标记int a;//算法选择标记printf("**********************************************************\n");printf("\t\t用以下三种方法实现主存空间的分配\n");printf("\t(1)首次适应算法\t(2)最佳适应算法\t(3)最差适应算法\n");printf("******************************** **************************\n");printf("\n");printf("请输入所使用的内存分配算法:");scanf("%d",&a);while(a<1||a>3){printf("输入错误,请重新输入所使用的内存分配算法:\n");scanf("%d",&a);}switch(a){case 1:printf("\n\t****使用首次适应算法:****\n");break;case 2:printf("\n\t****使用最佳适应算法:****\n");break;case 3:printf("\n\t****使用最坏适应算法:****\n");break;}Initblock(); //开创空间表while(1){show();printf("\t1: 分配内存\t2: 回收内存\t0: 退出\n");printf("请输入您的操作:");scanf("%d",&i);if(i==1)allocation(a); // 分配内存else if(i==2) // 内存回收{printf("请输入您要释放的分区号:");scanf("%d",&flag);recovery(flag);}else if(i==0){printf("\n退出程序\n");break; //退出}else //输入操作有误{printf("输入有误,请重试!");continue;}}}。
实验报告【实验名称】首次适应算法和循环首次适应算法【实验目的】理解在连续分区动态的存储管理方式下,如何实现主存空间的分配与回收。
【实验原理】首次适应(first fit,FF)算法FF算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区即可。
然后再按照作业的大小,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍留在空闲链中。
若从链首直至链尾都不能找到一个能满足要求的分区,则表明系统中已经没有足够大的内存分配给该进程,内存分配失败,返回。
循环首次适应(next fit,NF)算法为避免低址部分留下许多很小的空闲分区,以及减少查找可用空闲分区的开销,循环首次适应算法在为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块玉请求大小相等的内存空间分配给作业。
【实验内容】实现主存空间的分配与回收:1.采用可变式分区管理,使用首次适应算法实现主存空间的分配与回收;2.采用可变式分区管理,使用循环首次适应算法实现主存空间的分配与回收。
数据结构和符号说明:typedef struct PCB//进程控制块{char ProgressName[10]; //进程名称int Startaddress; //进程开始地址int ProgressSize; //进程大小int ProgressState = 0; //进程状态};typedef struct FREE //空闲区结构体{int Free_num; //空闲区名称int Startaddress; //空闲区开始地址int Endaddress; //空闲区结束地址int Free_Space; //空闲区大小};算法流程图:首次适应算法循环首次适应算法程序代码及截图:主界面:首次适应算法,初始空闲区:插入进程:插入3个进程:空闲区信息:删除进程2:删除后空闲区状况:再插入一个进程,可以看到其其初始地址为100:循环首次适应算法,插入3个进程删除进程2后:再插入进程A,发现其从上次找到的空闲分区的下一个空闲分区开始查找,其初始地址为750而不是200:。
操作系统-内存分配与回收实验报告本次实验是关于内存管理的实验,主要涉及内存分配和回收的操作。
本文将对实验过程和结果进行详细介绍。
1. 实验目的本次实验的主要目的是熟悉内存管理的基本原理和机制,掌握内存分配和回收的方法,并且实现一个简单的内存管理器。
2. 实验原理内存管理是操作系统的重要组成部分,主要负责管理计算机的内存资源,并且协调进程对内存的访问。
在计算机工作过程中,内存扮演着重要的角色,因此内存管理的效率和稳定性对计算机的性能和稳定性有着重要影响。
内存管理包括内存分配和回收两个方面。
内存分配是指为进程分配空闲的内存空间,以便程序可以执行;内存回收是指将已经使用完成的内存空间还回给系统,以便其他进程使用。
3. 实验步骤为了实现一个简单的内存管理器,我们需要进行以下步骤:(1)定义内存块结构体首先,我们需要定义一个内存块结构体,用于描述内存块的基本信息。
内存块结构体可以包含以下信息:· 内存块的起始地址· 内存块是否被分配下面是一个内存块结构体定义的示例代码:typedef struct mem_block{void *start_address; // 内存块的起始地址size_t size; // 内存块的大小bool is_allocated; // 内存块是否已经分配}MemBlock;(3)实现内存分配函数现在,我们可以开始实现内存分配函数了。
内存分配函数需要完成以下工作:· 在内存管理器中寻找一个合适的内存块void *mem_alloc(MemManager *manager, size_t size){MemBlock *p = manager->block_list;while(p){if(p->size >= size && !p->is_allocated){p->is_allocated = true;return p->start_address;}p = p->next;}return NULL;}· 找到该内存块所在的位置· 将该内存块标记为未分配状态4. 实验结果本次实验实现了一个简单的内存管理器,通过该内存管理器可以实现内存分配和回收的操作。
主存空间的分配与及回收实验报告一、实验目的:1.了解主存空间的分配与回收的基本原理;2.掌握主存空间分配与回收的常用算法;3.学会利用实验方法验证主存空间分配与回收的效果。
二、实验原理:1.主存空间的分配:静态分配是指在程序编译时,为程序分配固定大小的存储空间。
这种分配方式的缺点是无法适应不同大小的程序需求,造成了存储空间的浪费。
动态分配是指在程序运行时,根据需要动态分配存储空间。
常见的动态分配方式有两种:堆和栈。
堆是由程序员自行分配和释放的,栈是由系统自动分配和释放的。
动态分配的优点是能够根据需要分配合适的存储空间,减少了空间的浪费。
2.主存空间的回收:常见的回收方式有两种:手动回收和自动回收。
手动回收是指由程序员手动释放不再需要的存储空间。
这种回收方式的优点是能够具体控制存储空间的回收时间,但缺点是容易出现程序员忘记手动回收的情况,导致存储空间的浪费。
自动回收是指由系统自动回收不再需要的存储空间。
系统根据程序的运行情况自动判断哪些存储空间可以回收,并进行回收操作。
自动回收的优点是减少了程序员的工作量,保证存储空间的合理利用,但缺点是可能会出现不准确的判断,导致存储空间的泄漏。
三、实验步骤:本实验以C语言为例,通过编写一个简单的程序,模拟主存空间的分配与回收过程。
1.编写程序代码:#include <stdio.h>#include <stdlib.h>int maiint *p;p = (int *)malloc(sizeof(int) * 10);if (p == NULL)printf("内存分配失败!\n");exit(1);}int i;for (i = 0; i < 10; i++)p[i]=i*10;}for (i = 0; i < 10; i++)printf("%d ", p[i]);}printf("\n");free(p);return 0;2.编译并运行程序:在命令行中输入以下命令,编译并运行程序:gcc -o memory_allocation memory_allocation.c./memory_allocation3.实验结果分析:程序运行后,首先使用malloc函数分配了一块大小为sizeof(int)* 10的存储空间,用于存储10个整数。
第9章主存空间的分配与回收➢一实验内容:主存是中央处理机能直接存取指令和数据的存储器。
能否合理而有效地使用主存,在很大程度上将影响到整个计算机系统的性能。
实现主存空间的分配和回收。
➢二实验目的:本实验主要让大家熟悉主存的各种分配和回收。
所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收,就是当作业运行完成时,将作业或进程所占用的主存空间还给系统。
主存的分配与回收的实现是与主存储器的管理方式有关的。
通过本实验,帮助学生理解在不同的存储器管理方式下,如何实现主存空间的分配与回收。
➢三实验题目:提示:采用可变分区管理,使用适当的算法实现主存的分配和回收要求采用分区说明表进行。
提示:(1)可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量,查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若无,则作业等待。
随着作业的装入、完成,主存空间被分割成许多大大小小的分区。
有的分区被作业占用,有的分区空闲。
例如,某时刻主存空间占用情况如图3-1所示。
为了说明哪些分区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,如图3-2所示。
其中,起始地址指出各空闲区的主存起始地址,长度指出空闲区的大小。
状态:未分配----该栏目记录的是有效的空闲区;空表目----没有登记信息。
由于分区数目不定,所以空闲区说明表中应有足够的空表目项。
否则造成溢出,无法登记。
同样,再设一个已分配区表,记录作业或进程的主存占用情况。
(2)当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。
有时找到的空闲区可能大于作业需求量,这时应将空闲区一分为二。
一个分给作业;另一个仍作为空闲区留在空闲区表中。
为了尽量减少由于分割造成的碎片,尽可能分配低地址部分的空闲区,将较大空闲区留在高地址端,以利于大作业的装入。
操作系统实验_动态分区存储管理方式的主存分配回收//////////////////////////////////////////////////////////// // 功能:// 《计算机操作系统》实验// 首次适应性算法// 摸拟动态分区存储管理方式的主存分配和回收// 时间:// 2005-11-14////////////////////////////////////////////////////////////#include "iostream.h"#include "iomanip.h"#define ERR_NOFREEAREA 1#define ERR_NOADEQUACYAREA 2#define ERR_ALLOCATED 4#define ERR_NOJOBS 1#define ERR_NOSUCHJOB 2#define ERR_RECLAIMED 4typedef struct tagUsedNode{long address;long length;int flag; //作业名struct tagUsedNode *next;} USED_AREA , *USED_TABLE;typedef struct tagFreeNode{long address;long length;struct tagFreeNode *next;} FREE_AREA , *FREE_TABLE;//空闲区、作业区链表USED_TABLE usedTable = NULL;FREE_TABLE freeTable = NULL;//给作业分配空间//jobname: 作业名//jobsize: 作业所需空间大小int Allocate( int jobname , long jobsize )//如果没有空闲区if( freeTable == NULL )return ERR_NOFREEAREA;FREE_TABLE p = freeTable;FREE_TABLE q = p;//找首次适应空闲区while( p != NULL && p->length < jobsize ){q = p;p = p->next;}//如果找不到有足够空间的分区if( p == NULL )return ERR_NOADEQUACYAREA;USED_TABLE x = new USED_AREA;x->address = p->address;x->length = jobsize;x->flag = jobname;x->next = NULL;//如果该分区大于作业需求,空间大小减去作业大小if( p->length > jobsize ){p->length -= jobsize;p->address += jobsize;}//如果该分区等于作业大小,删除该分区else{if( p == freeTable )freeTable = NULL;elseq->next = p->next;delete p;}//作业加入“作业表”中USED_TABLE r = usedTable;USED_TABLE t = r;while( r != NULL && r->address < x->address ) {t = r;r = r->next;}if( usedTable == NULL )usedTable = x;else{x->next = r;t->next = x;}return ERR_ALLOCATED;}//回收作业空间//jobname: 作业名int Reclaim( int jobname ){if( usedTable == NULL )return ERR_NOJOBS;USED_TABLE p = usedTable;USED_TABLE q = p;while( p != NULL && p->flag != jobname ){q = p;p = p->next;}//如果没有该作业if( p == NULL )return ERR_NOSUCHJOB;//回收后的空间加入到空闲区FREE_TABLE r = freeTable;FREE_TABLE t = r;FREE_TABLE x;while( r != NULL && r->address < p->address ) {t = r;r = r->next;}x = new FREE_AREA;x->address = p->address;x->length = p->length;x->next = NULL;if( r == freeTable ){x->next = r;freeTable = x;t = freeTable;}else{x->next = r;t->next = x;}//合并分区while( t->next != NULL && t->address + t->length == t->next->address ) {t->length += t->next->length;r = t->next;t->next = t->next->next;delete r;}//删除该作业if( p == usedTable ){usedTable = usedTable->next;}elseq->next = p->next;delete p;return ERR_RECLAIMED;}int Init(){freeTable = new FREE_AREA;freeTable->address = 0;freeTable->length = 1024;freeTable->next = NULL;return 1;}void jobrequest(){int jobname;int jobsize;cout<<"...................."<<endl;cout<<"作业名: ";cin >> jobname;cout<<"作业长度: ";cin >> jobsize;if( Allocate( jobname , jobsize ) == ERR_ALLOCATED )cout<<"该作业已成功获得所需空间"<<endl;elsecout<<"该作业没有获得所需空间"<<endl;cout<<"...................."<<endl;}void jobreclaim(){int jobname;cout<<"...................."<<endl;cout<<"作业名: ";cin >>jobname;int result = Reclaim( jobname );if( result == ERR_RECLAIMED )cout<<"该作业已成功回收"<<endl;else if( result == ERR_NOSUCHJOB || result == ERR_NOJOBS )cout<<"系统没有作业或该作业不存在"<<endl;cout<<"...................."<<endl;}void freeTablePrint(){cout<<"........................................"<<endl;cout<<setw(10)<<"address"<<setw(10)<<"length"<<setw(10)<<"state"<<en dl<<endl;FREE_TABLE p = freeTable;USED_TABLE q = usedTable;int x , y;while( p || q ){if( p )x = p->address;elsex = 0x7fffffff;if( q )y = q->address;elsey = 0x7fffffff;if( x < y ){cout<<setw(10)<<p->address<<setw(10)<<p->length<<setw(10)<<"空闲"<<endl;p = p->next;}if( x > y ){cout<<setw(10)<<q->address<<setw(10)<<q->length<<setw(10)<<"已分配"<<setw(10)<<"ID="<<q->flag<<endl;q = q->next;}}cout<<"........................................"<<endl;}void main(){Init();int choose;bool exitFlag = false;while( !exitFlag ){cout<<"选择功能项( 0 -退出 1 - 分配主存 2 - 回收主存 3 - 显示主存)"<<endl; cout<<"?>";cin>>choose;switch( choose ){case 0:exitFlag = true;break;case 1:jobrequest();break;case 2:jobreclaim();break;case 3:freeTablePrint();break;}}}Trackback: /TrackBack.aspx?PostId=529025。
主存储器空间的分配和回收实验报告主存储器是计算机中一种重要的存储设备,它用于存储程序的指令和数据。
在计算机系统中,主存储器的空间分配和回收是一个关键的问题。
为了研究主存储器空间的分配和回收,我们进行了一系列实验。
实验目的:1.了解主存储器的空间分配和回收原理;2.掌握主存储器空间分配和回收的算法和方法;3.借助实验了解主存储器空间分配和回收对系统性能的影响。
实验步骤:1.设计一个模拟的主存储器,包括地址空间和物理存储空间。
我们将地址空间划分为多个固定大小的块,每个块对应一个页面。
2.实现主存储器的空间分配算法。
我们选择了最先适应算法,即从低地址开始寻找第一个可以容纳所需页面的空闲块。
3.实现主存储器的空间回收算法。
我们选择了简单的空闲块链表算法,即将回收的空间加入到一个空闲块链表中。
4.编写测试程序,模拟实际系统中的内存分配和回收操作。
测试程序包括创建新进程,分配内存空间,释放内存空间等操作。
5.对测试程序进行性能评测,比较不同算法和策略下的主存储器使用效率和系统性能。
实验结果:通过对实验数据的分析和对比,我们得出了以下结论:1.最先适应算法在空间分配方面具有较好的效果,能够快速找到合适的空闲块。
2.简单的空闲块链表算法能够有效地回收空间,减少内存碎片的产生。
3.不同的内存分配策略会对系统性能产生影响,合理选择内存管理算法是提高系统性能的关键。
结论:本次实验通过对主存储器空间的分配和回收进行实验研究,掌握了主存储器空间分配和回收的算法和方法,并通过实验结果对主存储器的性能进行了评估和分析。
实验结果表明最先适应算法和简单的空闲块链表算法是有效的方法,能够提高主存储器的使用效率和系统性能。
在实际系统中,我们需要根据具体情况选择合适的算法和策略,以满足系统的需求。
一、实验内容主存储器空间的分配和回收。
#include <stdio.h>#include<math.h>#define COUNT 512typedef struct NODE{char name;//名称float start;//起始位置float end;//大小int flag;//是否分配的标志}NODE;NODE OS[COUNT];//数组int count;//被分成的块数统计int applyfree;float numb;char c;//先对数组进行初始化,使没有分配的名称为P void init(){count=1;OS[0].name ='P';OS[0].start =0;OS[0].end =COUNT;OS[0].flag =1;}//对数组的插入操作void insert(int m,float st,float en){int i;count++;for(i=count;i>m+1;i--){OS[i]=OS[i-1];}OS[m].start =st;OS[m].end =en;}//移动操作,即对数组的删除操作void move(int m){int i;for(i=m;i<count-1;i++){OS[i]=OS[i+1];}count--;}//如果相邻块都没有分配,则要合并到一起void rremove(int m,float st,float en){if(!OS[m-1].flag &&!OS[m+1].flag ){OS[m].name ='P';OS[m].flag =1;}if(OS[m-1].flag ){OS[m-1].end =OS[m-1].end +en;move(m);}if(OS[m+1].flag ){OS[m].end =OS[m].end +OS[m+1].end ;OS[m].name ='P';OS[m].flag =1;move(m+1);}}//打印输出void show(){int i;printf("名称标识起址长度状态\n");for(i=0;i<count;i++){if(OS[i].flag )printf("P ");elseprintf("%c ",OS[i].name );printf("%d %1.0f %1.0f ",i,OS[i].start ,OS[i].end );if(OS[i].flag )printf("未分配\n");elseprintf("已分配\n");}}//从键盘输入数据void putin(){printf("请输入申请或者释放的进程名称及资源数量:\n");rewind(stdin);scanf("%c",&c);scanf("%d",&applyfree);scanf("%f",&numb);}int apply(){int i=0;int applyflag=0;int freeflag=0;if(applyfree)//提出申请资源{while(!applyflag&&i<count){if(OS[i].end >=numb&&OS[i].flag ){if(OS[i].end ==numb){OS[i].name =c;OS[i].flag =0;}else{insert(i+1,OS[i].start +numb,OS[i].end -numb);OS[i+1].flag =1;OS[i+1].name ='P';OS[i].start =OS[i].start ;OS[i].name =c;OS[i].end =numb;OS[i].flag =0;}applyflag=1;}i++;}if(applyflag){printf("申请成功!\n");return 1;}else{printf("申请失败!没有足够大的空闲空间。
计算机学院计算机科学与技术专业班学号姓名教师评定_________________ 实验题目主存空间的分配和回收一、实验目的熟悉主存的分配与回收。
理解在不同的存储管理方式下,如何实现主存空间的分配与回收。
掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。
二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。
所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。
可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。
同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。
同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。
三、实验主要仪器设备和材料实验环境硬件环境: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运行完毕,释放所占内存。
此时,作业4进入系统,要求分配200KB内存。
作业3、1运行完毕,释放所占内存。
此时又有作业5申请140KB,作业6申请60KB,作业7申请50KB。
为它们进行主存分配和回收。
1、采用可变分区存储管理,使用空闲分区链实现主存分配和回收。
空闲分区链:使用链指针把所有的空闲分区链成一条链,为了实现对空闲分区的分配和链接,在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针,由状态位指示该分区是否分配出去了;同时,在分区尾部还设置有一后向指针,用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间,当该分区分配出去后,状态位就由“0”置为“1”。
设置一个内存空闲分区链,内存空间分区通过空闲分区链来管理,在进行内存分配时,系统优先使用空闲低端的空间。
设计一个空闲分区说明链,设计一个某时刻主存空间占用情况表,作为主存当前使用基础。
初始化空间区和已分配区说明链的值,设计作业申请队列以及作业完成后释放顺序,实现主存的分配和回收。
要求每次分配和回收后显示出空闲内存分区链的情况。
把空闲区说明链的变化情况以及各作业的申请、释放情况显示打印出来。
2.采用可变分区存储管理,分别采用首次适应算法、最佳适应算法和最坏适应算法实现主存分配和回收。
3、主存空间分配(1)首次适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。
在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足要求的空闲区,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。
(2)最佳适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。
在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中(3)最坏适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。
在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。
4、主存空间回收当一个作业执行完成撤离时,作业所占的分区应该归还给系统。
归还的分区如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明链中,此时,相邻空闲区的合并问题,要求考虑四种情况:(1)释放区下邻空闲区(低地址邻接)(2)释放区上邻空闲区(高地址邻接)(3)释放区上下都与空闲区邻接(4)释放区上下邻都与空闲区不邻接五、程序流程图main函数里的流程图分配空间里的流程图回收空间里的流程图六、相关数据结构及关键函数说明本程序采用了一个struct free_table数据结构,里面包含分区序号(num)、起始地址(address)、分区长度(length)和分区状态(state)。
还用了线性表的双性链表存储结构(struct Node),里面包含前区指针(prior)和后继指针(next)。
一开始定义一条(含有first和end)的链,用开始指针和尾指针开创空间链表。
然后分别按三种算法进行分配和回收。
在该程序中关键函数有,sort()、allocation()、recovery()、和First_fit()、Best_fit ()、Worst_fit();其中sort()函数是用来整理分区序号的,如在删序号3时,她与前面序号2相连在一起了,然后序号2中的长度总满足申请的内存大小,就会在序号2中分配,然后序号在2的基础上加1,一直加,加到与原本序号3的下一个序号也就是4相等,这时sort()就开始有明显的工作了;allocation()是分配空间的,也是过渡到三个算法中的,当三个算法中满足或者不满足分配请求,都会又返回值给allocation();recovery()是用来回收内存的,里面包含了四种情况相连结果,即释放区上与空闲区邻接、释放区下与空闲区邻接、释放区上下都与空闲区邻接、释放区上下都与空闲区不邻接这四种情况的结果。
七、源代码#include<stdio.h>#include<stdlib.h>#define OK 1 //完成#define ERROR 0 //出错typedef int Status;typedef struct free_table//定义一个空闲区说明表结构{int num; //分区序号long address; //起始地址long length; //分区大小int state; //分区状态}ElemType;typedef struct Node// 线性表的双向链表存储结构{ElemType data;struct Node *prior; //前趋指针struct Node *next; //后继指针}Node,*LinkList;LinkList first; //头结点LinkList end; //尾结点int flag;//记录要删除的分区序号Status Initblock()//开创带头结点的内存空间链表{first=(LinkList)malloc(sizeof(Node));end=(LinkList)malloc(sizeof(Node));first->prior=NULL;first->next=end;end->prior=first;end->next=NULL;end->data.num=1;end->data.address=40;end->data.length=600;end->data.state=0;return OK;}void sort()//分区序号重新排序{Node *p=first->next,*q;q=p->next;for(;p!=NULL;p=p->next){for(q=p->next;q;q=q->next){if(p->data.num>=q->data.num){q->data.num+=1;}}}}//显示主存分配情况void show(){ int flag=0;//用来记录分区序号Node *p=first;p->data.num=0;p->data.address=0;p->data.length=40;p->data.state=1;sort();printf("\n\t\t》主存空间分配情况《\n");printf("**********************************************************\n\n");printf("分区序号\t起始地址\t分区大小\t分区状态\n\n");while(p){printf("%d\t\t%d\t\t%d",p->data.num,p->data.address,p->data.length);if(p->data.state==0) printf("\t\t空闲\n\n");else printf("\t\t已分配\n\n");p=p->next;}printf("**********************************************************\n\n"); }//首次适应算法Status First_fit(int request){//为申请作业开辟新空间且初始化Node *p=first->next;LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p){if((p->data.state==0)&&(p->data.length==request)){//有大小恰好合适的空闲块p->data.state=1;return OK;break;}else if((p->data.state==0) && (p->data.length>request)){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;temp->data.num=p->data.num;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.length;p->data.length-=request;p->data.num+=1;return OK;break;}p=p->next;}return ERROR;}//最佳适应算法Status Best_fit(int request){int ch; //记录最小剩余空间Node *p=first;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最小空间和最佳位置{if((p->data.state==0) && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length > p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.state=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//最差适应算法Status Worst_fit(int request){int ch; //记录最大剩余空间Node *p=first->next;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最大空间和最佳位置{if(p->data.state==0 && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length < p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.length=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//分配主存Status allocation(int a){int request;//申请内存大小printf("请输入申请分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("分配大小不合适,请重试!");return ERROR;}switch(a){case 1: //默认首次适应算法if(First_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 2: //选择最佳适应算法if(Best_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 3: //选择最差适应算法if(Worst_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;}}Status deal1(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.length+=q->next->data.length;q->next=q->next->next;q->next->next->prior=q;q->data.state=0;q->data.num=flag;}if(q->prior->data.state==0&&q->next->data.state==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}Status deal2(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=p->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.state=0;}if(q->prior->data.state==0&&q->next->data.state==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}//主存回收Status recovery(int flag){Node *p=first;for(;p!=NULL;p=p->next){if(p->data.num==flag){if(p->prior==first){if(p->next!=end)//当前P指向的下一个不是最后一个时{if(p->next->data.state==0) //与后面的空闲块相连{p->data.length+=p->next->data.length;p->next->next->prior=p;p->next=p->next->next;p->data.state=0;p->data.num=flag;}else p->data.state=0;}if(p->next==end)//当前P指向的下一个是最后一个时{p->data.state=0;}}//结束if(p->prior==block_first)的情况else if(p->prior!=first){if(p->next!=end){deal1(p);}else{deal2(p);}}//结束if(p->prior!=block_first)的情况}//结束if(p->data.num==flag)的情况}printf("\t****回收成功****");return OK;}//主函数void main(){int i; //操作选择标记int a;//算法选择标记printf("**********************************************************\n");printf("\t\t用以下三种方法实现主存空间的分配\n");printf("\t(1)首次适应算法\t(2)最佳适应算法\t(3)最差适应算法\n");printf("**********************************************************\n");printf("\n");printf("请输入所使用的内存分配算法:");scanf("%d",&a);while(a<1||a>3){printf("输入错误,请重新输入所使用的内存分配算法:\n");scanf("%d",&a);}switch(a){case 1:printf("\n\t****使用首次适应算法:****\n");break;case 2:printf("\n\t****使用最佳适应算法:****\n");break;case 3:printf("\n\t****使用最坏适应算法:****\n");break;}Initblock(); //开创空间表while(1){show();printf("\t1: 分配内存\t2: 回收内存\t0: 退出\n");printf("请输入您的操作:");scanf("%d",&i);if(i==1)allocation(a); // 分配内存else if(i==2) // 内存回收{printf("请输入您要释放的分区号:");scanf("%d",&flag);recovery(flag);}else if(i==0){printf("\n退出程序\n");break; //退出}else //输入操作有误{printf("输入有误,请重试!");continue;}}}八、执行结果和结果分析初始化首次适应算法:当作业1、2、3顺利分配内存空间后:回收序号2里面的内存:分配作业4:回收序号3里面的内存(与上邻序号2相连了)回收序号1里的内存(与下邻序号2相连了)继续分配(会发现总是按顺序查找满足要求的第一个空闲块,一旦发现就会分配):初始化最佳适应算法:继续分配(会发现总是查找满足要求的空闲块且其比其他空闲块长度小,一旦发现就会分配):初始化最坏适应算法:继续分配(会发现总是查找满足要求的空闲块且其比其他空闲块长度小,一旦发现就会分配):九、所遇困难的解决以及心得体会本实验我采取用一条链表同时表示空闲分区链和主存空间占用情况,因为主存总大小是固定的,把空闲分区链所表示的区域从总的内存里去除就是被占用的空间的大小,这个实验还是比较简单的,但在执行过程中还是遇到了很多问题,如在回收空间的函数中,因为要考虑到四种情况,我一开始的想法是这样的:让p指向链表开头,一直等找到p所指向的分区序号等于要删除的分区序号,然后开始执行,当p->prior不是链首first时要考虑p->next是不是链尾end,然后继续考虑p的前向指针和后向指针得状态是否为空闲;等考虑完p->prior 不是链首了,就进行考虑p->prior是链首的问题,然后又进行了考虑p->next是不是链尾end,然后继续考虑p的前向指针和后向指针得状态是否为空闲;等考虑完了p->prior的问题又进行考虑p->next的问题,一直这样重复了,我都不知道,当时超烦的,后来静下心重新检查自己写得程序,才知道自己写得这个函数好凌乱。