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

free_quantity++; fscanf(文件指针,格式字符串,输入表列);}return 1;}return 0;}void sort(){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].address<frees[p].address){p=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}void view(){int i;cout<<endl<<"mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"<< endl;cout<<"输出空闲区表:\n起始地址分区长度状态\n"<<endl;for(i=0;i<free_quantity;i++){(2);(12);cout<<frees[i].address;(10);cout<<frees[i].length;(8);cout<<frees[i].tag<<endl;}cout<<endl<<"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"< <endl;cout<<"输出已分分区表:\n起始地址分区长度占用作业名\n"<<endl;for(i=0;i<occupy_quantity;i++){(2);(12);cout<<occupys[i].address;(10);cout<<occupys[i].length;(8);cout<<occupys[i].tag<<endl;}}void ear(){char job_name[10];int job_length;int i,j,flag,t;cout<<"请输入分配内存的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){ ength>=job_length){flag=1;}}if(flag==0){ ength>=job_length){ddress=frees[i].address; ag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].address+=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 reclaim()ag,job_name)){flag=i;address=occupys[i].address;length=occupys[i].length;}}if(flag==-1){ ddress+frees[i].length)==address){if(((i+1)<free_quantity)&&(frees[i+1].address==address+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].address==(address+length)){frees[i].address=address;frees[i].length+=length;p=1;}}if(p==0){frees[free_quantity].address=address;frees[free_quantity].length=length;free_quantity++;}ddress=-1;ength=0;strcpy(frees[i].tag,"free");occupys[i].address=-1;ength=0;strcpy(occupys[i].tag,"");}free_quantity=0;occupy_quantity=0;flag=read();while(flag==1){sort();cout<<"选择功能项: (0-退出,1-分配内存,2-回收内存,3-显示内存)\n"<<endl;cout<<"选择功项(0-3):";cin>>chioce;switch(chioce){case 0:flag=0;break;case 1:ear();break;case 2:reclaim();break;case 3:view();break;default:cout<<"没有该选项\n"<<endl;}}}。
可变分区存储管理方案中的内存分配

可变分区存储管理方案中的内存分配用户提出内存空间的申请;系统根据申请者的要求,按照一定的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者;当程序执行完毕或主动归还内存资源时,系统要收回它所占用的内存空间或它归还的部分内存空间。
1.程序运行时首先接收输入:空闲区数据文件,包括若干行,每行有两个数据项:起始地址、长度(均为整数),各数据项以逗号隔开。
2.建立空闲区表并在屏幕上显示输出空闲区表内容,空闲区表中记录了内存中可供分配的空闲区的始址和长度,用标志位指出该分区是否是未分配的空闲区。
3.从用户界面根据用户提示接收一个内存申请,格式为:作业名、申请空间的大小。
4.按照最差(最坏)适配算法选择一个空闲区,分割并分配,修改相应的数据结构(空闲区表),填写内存已分配区表(起始地址、长度、标志位),其中标志位的一个作用是指出该区域分配给哪个作业。
5.重复3、4,直到输入为特殊字符(0)。
6.在屏幕上显示输出新的空闲区表和已分配区表的内容#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX 10struct data1 /*空闲区表*/{int address;int length;int flag;};struct data2 /*已分配区表*/{int address;int length;char name[20];};struct data1 empty[MAX];struct data2 busy[MAX];void initialize( );int read_data( ); /*从文件中读如数据*/void display_empty_table(int); /*显示空闲区表*/void display_busy_table(int); /*显示已分配区表*/void badest_fit( int *,int *,char *name,int s );/*最坏适应算法*/void first_fit( int *,int *,char *name,int s ); /*最先适应算法*/void best_fit( int *,int *,char *name,int s ); /*最佳适应算法*/void main( ){int num1,num2,size; /*num1用于统计空闲表的,num2用于统计分配区表*/ char name[20];num2=0;initialize( ); /*初始花空闲区表和分配区表*/num1=read_data( );if( num1==0 ) /*表示文件中没有数据*/printf("there has no data in empty table\n");printf("the initialial empty table is:\n");display_empty_table( num1 ); /*显示空闲区表*/while(1){printf("please input job's name and job's size\n");puts("input exit to exit");scanf("%s",name);if( strcmp(name,"exit")==0 ){getch( );break;}scanf("%d",&size);badest_fit( &num1,&num2,name,size );/*这里可以改为最佳适应和最先适应*/ }puts("the empty table after assigning");display_empty_table( num1 );puts("the busy table:");display_busy_table( num2 );}void initialize( ){int i;for( i=0;i<MAX;i++ ){empty[i].address=0;empty[i].length=0;empty[i].flag=0;busy[i].address=0;busy[i].length=0;strcpy(busy[i].name,"");}}int read_data( ){FILE *fp;int n=0;fp=fopen("A.txt","rb");if( fp==NULL ){puts("can't open A.txt");getch( );exit(1);}while( !feof(fp) ){fscanf(fp,"%d,%d",&empty[n].address,&empty[n].length);if( feof(fp) )break;n++;}fclose(fp);return n;}void display_empty_table( int num ){int i;printf("address\tlength\tflag\n");for( i=0;i<num;i++ )printf("%d\t%d\t%d\n",empty[i].address,empty[i].length,empty[i].flag); printf("\n");}void display_busy_table( int num ){int i;printf("address\tlength\tname\n");for( i=0;i<num;i++ )printf("%d\t%d\t%s\n",busy[i].address,busy[i].length,busy[i].name); printf("\n");}void badest_fit( int *n1,int *n2,char *name,int s ){int i,temp;temp=0;for( i=0;i<*n1;i++ ) /*寻找最大的空闲区*/if( empty[i].length>empty[temp].length)temp=i;if( s>empty[temp].length) /*申请的空间比最大的空闲区还大*/{printf("the size of memory is not enough\n");return;}busy[*n2].address=empty[temp].address;/*修改分配区表*/busy[*n2].length=s;strcpy( busy[*n2].name,name );(*n2)++;if( s==empty[temp].length ) /*若申请的空间与空闲区恰好相等*/ {for( i=temp+1;i<*n1;i++ )empty[i-1]=empty[i];(*n1)--;}else{empty[temp].address+=s;empty[temp].length-=s;}}/*最先适应算法*/void first_fit( int *n1,int *n2,char *name,int s ){int i,temp;temp=0;for( i=0;i<*n1;i++ ) /*寻找第一块空闲区*/if( empty[i].length>=s ){temp=i;break;}if( i>=*n1){printf("the size of memory is not enough\n");return;}busy[*n2].address=empty[temp].address;busy[*n2].length=s;strcpy( busy[*n2].name,name );(*n2)++;if( s==empty[temp].length ){for( i=temp+1;i<*n1;i++ )empty[i-1]=empty[i];(*n1)--;}else{empty[temp].address+=s;empty[temp].length-=s;}}/*最佳适应算法*/void best_fit( int *n1,int *n2,char *name,int s ){int i,temp;temp=0;for( i=0;i<*n1;i++ ) /*寻找最佳的空闲区*/if( empty[i].length>=s ){temp=i;break;}if( i>=*n1){printf("the size of memory is not enough\n");return;}for(i=temp+1;i<*n1;i++ ){if(empty[i].length>s&&empty[i].length<empty[i].length ) {temp=i;}}busy[*n2].address=empty[temp].address;busy[*n2].length=s;strcpy( busy[*n2].name,name );(*n2)++;if( s==empty[temp].length ){for( i=temp+1;i<*n1;i++ )empty[i-1]=empty[i];(*n1)--;}else{empty[temp].address+=s;empty[temp].length-=s; }}测试文件0,200200, 600800, 8001700, 1001800, 500。
实验四可变分区存储管理方式的内存分配和回收

实验四实验四可变分区存储管理方式的内存分配和回收一.实验目的通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。
二.实验属性设计三.实验内容1.确定内存空间分配表;2.采用最优适应算法完成内存空间的分配和回收;3.编写主函数对所做工作进行测试。
四.实验背景材料实现可变分区的分配和回收,主要考虑的问题有三个:第一,设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计内存分配算法;第三,在设计的数据表格基础上设计内存回收算法。
首先,考虑第一个问题,设计记录内存使用情况的数据表格,用来记录空间区和作业占用的区域。
由于可变分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随内存分配和回收变动。
总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。
由于分区长度不同,因此设计的表格应该包括分区在内存中的起始地址和长度。
由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收内存分区时,可能会合并空闲分区,这样如果整个内存采用一张表格记录己分分区和空闲区,就会使表格操作繁琐。
分配内存时查找空闲区进行分配,然后填写己分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。
由此可见,内存的分配和回收主要是对空闲区的操作。
这样为了便于对内存空间的分配和回收,就建立两张分区表记录内存使用情况,一张表格记录作业占用分区的“己分分区表”;一张是记录空闲区的“空闲区表”。
这两张表的实现方法一般有两种:一种是链表形式,一种是顺序表形式。
在实验中,采用顺序表形式,用数组模拟。
由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。
它们的长度必须是系统可能的最大项数。
“已分分区表”的结构定义#define n 10 //假定系统允许的最大作业数量为nstruct{ float address; //已分分区起始地址float length; //已分分区长度、单位为字节int flag; //已分分区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名}used_table[n]; //已分分区表“空闲区表”的结构定义#define m 10 //假定系统允许的空闲区最大为mstruct{ float address; //空闲区起始地址float length; //空闲区长度、单位为字节int flag; //空闲区表登记栏标志,“0”表示空栏目,“1”表示未分配}used_table[n]; //空闲区表第二,在设计的数据表格基础上设计内存分配。
可变分区存储管理方式的内存分配和回收教程文件

typedef struct node{
int address;
int length;
char tag[10];
}job;
job frees[MJ];
int free_quantity;
job occupys[MJ];
int occupy_quantity;
int read()
{
FILE *fp;
char fn[10];
}
cout<<endl<<"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"<<endl;
cout<<"输出已分分区表:\n起始地址分区长度占用作业名\n"<<endl;
for(i=0;i<occupy_quantity;i++){
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){
strcpy(occupys[occupy_quantity].tag,job_name);
计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收

计算机操作系统内存管理系统可变分区存储管理方式的内存分配回收内存管理是操作系统中非常重要的一个功能,它负责管理计算机内存资源的分配和回收。
内存分配是指在程序运行时,为进程分配适当大小的内存空间;内存回收是指当进程终止或不再需要分配的内存时,将它们释放回系统。
可变分区存储管理方式是一种常用的内存管理方式,它的特点是将内存分为若干个可变大小的分区。
下面将详细介绍可变分区存储管理方式的内存分配和回收。
一、内存分配:1. 首次适应算法(First Fit):从起始地址开始查找第一个满足分配要求的可用分区,分配其中一部分给进程,并将剩余部分作为新的可用分区。
2. 循环首次适应算法(Next Fit):与首次适应算法类似,但是从上一次分配的位置开始查找。
3. 最佳适应算法(Best Fit):在所有可用分区中找到最小且能满足分配要求的分区进行分配。
4. 最坏适应算法(Worst Fit):在所有可用分区中找到最大的空闲分区进行分配。
这种方法可能会造成大量外部碎片,但可以更好地支持大型进程。
二、内存回收:1.碎片整理:在每次回收内存时,可以通过将相邻的空闲分区合并为一个更大的分区来减少外部碎片。
这种方法需要考虑如何高效地查找相邻分区和合并它们。
2.分区分割:当一个进程释放内存时,生成的空闲分区可以进一步划分为更小的分区,并将其中一部分分配给新进程。
这样可以更好地利用内存空间,但会增加内存分配时的开销。
3.最佳合并:在每次回收内存时,可以选择将相邻的空闲分区按照最佳方式合并,以减少外部碎片。
4.分区回收:当一个进程终止时,可以将其所占用的分区标记为可用,以便其他进程使用。
三、优化技术:1.预分配内存池:为了避免频繁的内存分配和回收,可以预分配一定数量的内存作为内存池,由进程从内存池中直接分配和回收内存。
2.内存压缩:当内存不足时,可以通过将一部分进程的内存内容移动到磁盘等外部存储器中,释放出一定的内存空间。
3.页面替换算法:在虚拟内存系统中,当物理内存不足时使用页面替换算法,将不常用的页面淘汰出物理内存,以便为新页面分配内存。
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号:2一、实验目的深入理解动态分区存储管理方式下的内存空间的分配与回收。
二、实验内容编写程序完成动态分区存储管理方式下的内存分配和回收的实现。
具体内容包括:确定用来管理内存当前使用情况的数据结构;采用首次适应算法完成内存空间的分配;分情况对作业进行回收;编写主函数对所做工作进行测试。
三、实验原理分配:动态分区存储管理方式把内存除OS占用区域外的空间看作一个大的空闲区。
当作业要求装入内存时,根据作业需要内存空间的大小查询内存中各个空闲区,当从内存中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业要求划出一个分区装入该作业。
回收:作业执行完后,它所占用的内存空间被收回,成为一个空闲区。
如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。
四、实验方法实现动态分区的分配与回收,主要考虑三个问题:第一、设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域(利用结构体类型数组来保存数据);第二、在设计的数据表格基础上设计内存分配算法(采用首次适应算法找合适的分区(对空闲分区表进行排序),分配时要考虑碎片问题);第三、在设计的数据表格基础上设计内存回收算法(分四种情况进行回收(上邻、下邻、上下邻和无相邻分区)。
五、实验步骤第一,设计记录内存使用情况的数据表格λ已分配分区表:起始地址、长度、标志(0表示“空表项”,1表示“已分配”)λ空闲分区表:起始地址、长度、标志(0表示“空表项”,1表示“未分配”)struct used_table { float address;//已分分区起始地址float length;//已分分区长度,单位为字节int flag;//已分配表区登记栏标志,用0表示空栏目,char zuoyename;};//已分配区表Struct free_table[ { float address;//空闲分区起始地址float length;//空闲分区长度,单位为字节int flag;//空闲分区表登记栏目用0表示空栏目,1表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。
实验四:主存空间的分配与回收实验
0 10k主存空间的分配和回收一、实验目的设计一个可变式分区分配的存储管理方案。
并模拟实现分区的分配和回收过程。
对分区的管理法可以是下面三种算法之一: 首次适应算法 循环首次适应算法 最佳适应算法二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。
所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。
可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、循环首次适应算法、最佳适应算法三种算法来实现主存的分配与回收。
同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。
三、实验主要仪器设备和材料实验环境:硬件环境:IBM-PC 或兼容机 软件环境:Visual C++6.0四、实验原理及设计方案采用可变分区管理,使用首次或最佳适应算法实现主存的分配和回收1、可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。
随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。
为了说明那些分区是空闲的,可以用来装入新作业,必须有一张空闲说明表 例如:空闲区说明表格式如下:第二栏其中,起址——指出一个空闲区的主存起始地址,长度指出空闲区的大小。
实验报告 可变分区 主存分配回收
printf("========================================\n");
printf("输入你的选择:\n");
scanf("%d",&j);
switch(j)
{
case 1:insertu(i);//为作业分配空间
//合并完之后的空闲分区的结束地址和相邻的空闲分区的起始地址也相连,则继续合并
{
fr[i].len=fr[i].len+fr[i+1].len;
for(k=i+1;k<m-1;k++)
{
fr[k].ad=fr[k+1].ad;
fr[k].len=fr[k+1].len;
fr[k].state=fr[k+1].state;
操作系统实验报告
设计题目
在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收
一、设计内容
主存储器空间的分配和回收。
二、设计目的
一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。主存的分配和回收的实现虽与主存储器的管理方式有关的,通过本实习帮助学生理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
{
while(fr[i].state!='M')
可变分区的主存分配和回收的算法
可变分区的主存分配和回收的算法下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!1. 引言在操作系统中,可变分区的主存分配和回收是一个重要的主题。
可变分区存储管理方式的内存分配和回收实验报告
可变分区存储管理方式的内存分配和回收实验报告【实验报告】一、实验目的了解可变分区存储管理方式的内存分配和回收过程,了解最优算法的原理和实现方法,掌握最优算法在可变分区存储管理方式下的内存分配和回收操作。
二、实验原理最优算法的分配过程如下: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}五、实验总结通过本次实验,我对可变分区存储管理方式的内存分配和回收过程有了更深入的了解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四实验四可变分区存储管理方式的内存分配和回收一.实验目的通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。
二.实验属性设计三.实验内容1.确定内存空间分配表;2.采用最优适应算法完成内存空间的分配和回收;3.编写主函数对所做工作进行测试。
四.实验背景材料实现可变分区的分配和回收,主要考虑的问题有三个:第一,设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计内存分配算法;第三,在设计的数据表格基础上设计内存回收算法。
首先,考虑第一个问题,设计记录内存使用情况的数据表格,用来记录空间区和作业占用的区域。
由于可变分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随内存分配和回收变动。
总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。
由于分区长度不同,因此设计的表格应该包括分区在内存中的起始地址和长度。
由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收内存分区时,可能会合并空闲分区,这样如果整个内存采用一张表格记录己分分区和空闲区,就会使表格操作繁琐。
分配内存时查找空闲区进行分配,然后填写己分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。
由此可见,内存的分配和回收主要是对空闲区的操作。
这样为了便于对内存空间的分配和回收,就建立两张分区表记录内存使用情况,一张表格记录作业占用分区的“己分分区表”;一张是记录空闲区的“空闲区表”。
这两张表的实现方法一般有两种:一种是链表形式,一种是顺序表形式。
在实验中,采用顺序表形式,用数组模拟。
由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。
它们的长度必须是系统可能的最大项数。
“已分分区表”的结构定义#define n 10 //假定系统允许的最大作业数量为nstruct{ float address; //已分分区起始地址float length; //已分分区长度、单位为字节int flag;//已分分区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名}used_table[n]; //已分分区表“空闲区表”的结构定义#define m 10 //假定系统允许的空闲区最大为mstruct{ float address; //空闲区起始地址float length; //空闲区长度、单位为字节int flag; //空闲区表登记栏标志,“0”表示空栏目,“1”表示未分配}used_table[n]; //空闲区表第二,在设计的数据表格基础上设计内存分配。
装入一个作业时,从空闲区表中查找满足作业长度的未分配区,如大于作业,空闲区划分成两个分区,一个给作业,一个成为小空闲分区。
实验中内存分配的算法采用“最优适应”算法,即选择一个能满足要求的最小空闲分区。
可变分区方式的内存分配流程如图。
第三,在设计的数据表格基础上设计内存回收问题。
内存回收时若相邻有空闲分区则合并空闲区,修改空闲区表。
可变分区方式的内存回收流程如图。
五.实验报告1.写出你编写的C语言程序。
2.描述可变分区存储管理的算法和思路。
3.总结体会可变分区存储管理方法。
六、参考程序#define n 10 //假定系统允许的最大作业数量为n#define m 10 //假定系统允许的空闲区最大为m#define minisize 100struct{ float address; //已分分区起始地址float length; //已分分区长度、单位为字节int flag; //已分分区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名}used_table[n]; //已分分区表struct{ float address; //空闲区起始地址float length; //空闲区长度、单位为字节int flag; //空闲区表登记栏标志,“0”表示空栏目,“1”表示未分配}used_table[n]; //空闲区表allocate(J,xk) //采用最优分配算法分配xk大小的空间char J;float xk;{int i,k;float ad;k=-1;for(i=0;i<m;i++) //寻找空间大于xk的最小空闲区登记项if(free_table[i].length>=xk&&free_table[i].flag==1)if(k==-1||free_table[i].length<free_table[k].length)k=i;if(k==-1) //未找到空闲区,返回{printf("无可用的空闲区\n");return;}//找到可用空闲区,开始分配;若空闲区大小与要求分配的空间差小于minisize大小,则空闲区全部分配;//若空闲区大小与要求分配的空间差大于minisize大小,则从空闲区划分一部分分配if(free_table[k].length-xk<=minisize){free_table[k].flag=0;ad=free_table[k].address;xk=free_table[k].length;} else{free_table[k].length=free_table[k].length-xk;ad=free_table[k].address+free_table[k].length;}//修改已分配区表i=0;while(used_table[i].flag!=0&&i<n) //寻找空表目i++;if(i>=n) //无表目填写已分分区{printf("无表目填写以分分区,错误\n");if(free_table[k].flag==0) //前面找到的是整个空闲区free_table[k].flag=1;else //前面找到的是某个空闲区的一部分free_table[k].length=free_table[k].length+xk;return;}else //修改已分配区表{used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;}return;}//内存分配函数结束reclaim(J) //回收作业名为J的作业所占的内存空间char J:{int i,k,j,s,t;float S,L;//寻找已分分区表中对应的登记项S=0;while((used_table[S].flag!=J||used_table[S].flag==0)&&S<n)S++;if(S>=n) //在已分分区表中找不到名字为J的作业{printf("找不到该作业\n");return;}//修改已分分区表used_table[S].flag=0;//取得归还分区的起始地址S和xxLS=used_table[S].address;L=used_table[S].length;j=-1;k=-1;i=0;//寻找回收分区的上下邻空闲区,上邻表目K,下邻表目Jwhile(i<m&&(j==-1||k==-1)){if(free_table[i].flag==0){if(free_table[i].address+free_table[i].length==0) k=i; //找到上邻{if(free_table[i].address==S+L) j=1; //找到下邻}i++;}if(k!=-1)if(j!=-1) //上邻空闲区,下邻空闲区,三项合并{free_table[k].length=free_table[j].length+free_table[k].length+L;free_table[j].fl ag+0;}else //上邻空闲区,下邻非空闲区,与上邻合并free_table[k].length=free_table[k].length+L;elseif(j!=-1) //上邻非空闲区,下邻空闲区,与下邻合并{free_table[j].address=S;free_table[j].length=free_table[j].length+L;} else{ //上下邻均为非空闲区,回收区域直接填入t=0; //在空闲区表中寻找空栏目while(free_table[t].flag==1&&t<m)t++;if(t>=m) //空闲区表满,回收空间失败,将已分配分区表复原{printf("内存空闲表没有空间,回收空间失败\n");used_table[S].flag=J;return;}free_table[t].address=s;free_table[t].length=l;free_table[t].flag=1;}return(true);} //内存回收函数结束main(){ int i,a;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=1;i<n;i++)used_table[i].flag=0;while(1){printf("选择功能项(0—退出,1—分配内存,2-回收内存,3-显示内存)\n");printf("选择功项(0-3):");scanf("%d",&a);switch(a){case 0;exit(0); //a=0程序结束case 1; //a=1分配内存空间printf("输入作业名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起始地址分区xx标志\n");for(i=0;i<m;i++)printf("%5.0f%10.0f%6d\n",free_table[i].address,free_table[i].length,free_table[i].flag);printf("按任意键,输出已分分区表\n");getch();printf("输出已分分区表:\n起始地址分区xx标志\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].length,used_table[i].flag); elseprintf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].length,used_table[i].flag); break;default:printf("没有该选项\n");}}}。