可变分区存储管理方式的内存分配和回收实验报告(最优算法)

合集下载

实验报告二主存空间的分配和回收

实验报告二主存空间的分配和回收
temp=freeTab; /*寻找空闲表中对应登记项*/
if(strcmp(PName,"OS")==0)
{ printf("ERROR!");
return;
}
while((strcmp(temp->proID,PName)!=0||temp->flag==1)&&temp)
temp=temp->next;
四、程序中使用的数据结构及符号说明
结构1:
typedef struct freeTable
{
char proID[6];
int startAddr; /*空闲区起始地址*/
int length; /*空闲区长度,单位为字节*/
int flag; /*空闲区表登记栏标志,用"0"表示空表项,用"1"表示未分配*/
freeNode=freeNode->next;
}
getchar();
break;
default:printf("没有该选项\n");
}/*case*/
}/*while*/
}/*main()*/
六、运行调试结果
初始界面:
分配主存,五个作业名:P1、P2、P3、P4、P5
显示主存使用情况:
回收主存P2:
if(front->flag==1&&rear->flag==1)
/* 上邻空闲区,下邻空闲区,三项合并*/
{
front->length=front->length+rear->length+temp->length;

实验7 可变分区

实验7 可变分区

实验7 可变分区管理实验内容内存是中央处理机能直接存取指令和数据的存储器。

能否合理而有效的使用内存,在很大程度上将影响到整个计算机系统的性能。

本实验实现内存空间的分配与回收。

实验目的本实验主要让大家熟悉内存的各种分配和回收。

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

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

内存的分配与回收的实现是与内存的管理方式有关的。

通过本实验,帮助大家理解不同的存储管理方式下,如何实现内存空间的分配与回收。

实验题目采用可变式分区管理,使用首次适应算法实现内存的分配与回收要求采用分区说明表进行实验。

提示:(1) 可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数可以调整。

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

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

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

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

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

其中,起始地址指出个空闲区的内存起始地址,长度指出空闲区的大小。

状态(未分配:该栏目记录的是有效空闲区) 状态(空表目:没有登记信息) 由于分区个数不定,所以空闲区说明表中应该有足够的空表目项。

否则造成溢出,无法登记。

同样,再设一个已分配表,记录作业或进程的内存占用情况。

(2) 当有一个新作业要求装入内存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需求量,这时应将空闲区一分为二。

一个分给作业,另外一个作为空闲区留在空闲区表中。

为了尽量减少由于分割造成的碎片,尽可能分配低地址部分的空闲区,将较大空闲区留在高地址端,以利于大作业的装入。

为此在空闲区表中,按空闲区首地址从低到高进行登图1 内存空间占用情况65K110K256K0 20K45K 10K记。

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

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

实验三可变分区存储管理方式的内存分配回收一.实验目的(1)深入了解可变分区存储管理方式的内存分配回收的实现。

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

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

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

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

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

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

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

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

四.实验部分源程序#include <iostream>using namespace std;typedef struct SNode { // Space Nodeint start,end; // 起始,结束int length; // 长度大小struct SNode *next; // 指向下一结点的指针}* SP;SP Head=(SP)malloc(sizeof(SNode)); // 全局变量,内存空间头结void DispSpace() { // 显示内存空间分配情况SP p=Head->next;cout<<"\n 空闲区说明表\n"<<"---地址--长度---\n";while (p){cout<<" "<<p->start<<" "<<p->length<<endl;p=p->next;}cout<<"----------------\n";}void Initial() { // 初始化说明表SP p,q;p=(SP)malloc(sizeof(SNode));q=(SP)malloc(sizeof(SNode));p->start=14; p->length=12; p->end=26;q->start=32; q->length=96; q->end=128; // 指导书上的作业分配Head->next=p; // 与头结点连接p->next=q;q->next=NULL;DispSpace();}void Allocation(int len) { // 分配内存给新作业SP p=Head->next,q;while (p){if (p->length < len)p=p->next;else if (p->length > len){p->start=p->start+len;p->length=p->length-len;cout<<"分配成功!\n";DispSpace(); return;}else{//当两者长度相等q=p->next;p->next=q->next;cout<<"分配成功!\n";DispSpace(); return;}}cout<<"分配失败!\n";DispSpace(); return;}void CallBack(int sta,int len) { // 回收内存SP p=Head,q=p->next,r; // 开始地址和长度p->end=0;int en=sta+len;while (q) {if (sta == 0) { // 初始地址为0if (en == q->start) { // 正好回收q->start=0;q->length=q->end;return;}else {r=(SP)malloc(sizeof(SNode));r->start=sta; r->length=len; r->end=en;p->next=r;r->next=q;return;}}else if ((p->end < sta) && (q->start > en)) { // 上邻区r=(SP)malloc(sizeof(SNode));r->start=sta; r->length=len; r->end=en;p->next=r;r->next=q;return;}else if ((p->end < sta) && (q->start == en)) { // 邻区相接q->start=sta;q->length=q->end-sta;return;}else if ((p->end == sta) && (q->start < en)) { // 下邻区p->end=en;p->length=en-p->start;return;}else if (p->end==sta && q->start==en) { // 邻区相接p->end=q->end;p->length=p->end-p->start;p->next=q->next;return;}else {p=p->next;q=q->next;}}}void main() {Initial();cout<<"现在分配大小为6K 的作业4 申请装入主存: ";Allocation(6); // 分配时参数只有长度//--------指导书测试数据演示----------cout<<"现回收作业 3 (起址10,长度4)\n";CallBack(10,4);DispSpace();cout<<"现回收作业 2 (起址26,长度6)\n";CallBack(26,6);DispSpace();//---------------演示结束-------------system("pause");}五.实验结果与体会我的体会:下面红色部分是赠送的总结计划,不需要的可以下载后编辑删除!2014年工作总结及2015年工作计划(精选)XX年,我工区安全生产工作始终坚持“安全第一,预防为主,综合治理”的方针,以落实安全生产责任制为核心,积极开展安全生产大检查、事故隐患整改、安全生产宣传教育以及安全生产专项整治等活动,一年来,在工区全员的共同努力下,工区安全生产局面良好,总体安全生产形势持续稳定并更加牢固可靠。

在可变分区管理方式下采用最先适应算法实现主存储器的分配和回收。

在可变分区管理方式下采用最先适应算法实现主存储器的分配和回收。
l.addJob(10,3,jobArray);
System.out.println("...............删除作业2后的内存情况....................");
l.delete(jobArray,2);
System.out.println("...............此后再添加作业4后的内存情况....................");
Link l = new Link();
System.out.println("...................起始的内存..................................");
jobArray[0].print();
System.out.println(".....................增加第一个作业后的内存情况.....................");
实验
一、实验目的
帮助学生理解在不同的存储管理方式下应如何实现主存空间的分配和回收。理解好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能够合理地分配和使用这些存储空间。
二、实验环境
1、Java环境
三、实验时数:

1.在可变分区管理方式下采用最先适应算法实现主存储器的分配和回收。
}
else{ //当下一块内存已被使用,那么继续寻找一块还没被使用的内存
for(int j=i+1;j<a.length-1;j++){
if(a[j]==null){
a[j]=new Node(size+a[j-1].start,size,true,jobNo);

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

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

可变分区存储管理实验报告一、实验目的了解可变分区存储管理的原理和方法,掌握可变分区分配和回收的算法。

二、实验内容使用C语言编写一个模拟的存储管理系统,实现可变分区存储管理的算法。

三、实验原理首次适应算法是指分配分区时,从第一个空闲分区开始查找,找到第一个能够满足要求的分区进行分配。

最佳适应算法是指分配分区时,从所有空闲分区中找到最小且大于等于要求的分区进行分配。

最坏适应算法则是指分配分区时,从所有空闲分区中找到最大的分区进行分配。

分配分区时,需要考虑一些问题,如分区大小是否满足要求,是否有足够的空闲分区,以及如何更新空闲分区表等。

回收分区时,需要考虑将回收的分区加入空闲分区表,并且可能需要合并相邻的空闲分区,以获得更大的空闲分区。

四、实验步骤1.定义作业结构体,包含作业名、作业大小等字段。

2.定义分区结构体,包含分区号、分区大小等字段。

3.初始化空闲分区表,将整个内存作为一个空闲分区,插入空闲分区表中。

4.进入循环,接受用户输入的指令,包括分配作业、回收作业和退出程序。

5.根据用户指令进行相应的操作,包括按首次适应、最佳适应或最坏适应算法进行分配作业,将分配和回收的分区加入空闲分区表。

6.根据用户指令输出当前空闲分区表和已分配的作业表。

7.重复步骤4-6,直到用户输入退出指令。

五、实验结果与分析经过多次测试,可变分区存储管理系统能够成功实现各种分区算法的分配和回收。

根据实验结果可以看出,首次适应算法的分配速度较快,但可能会产生较多的碎片。

最佳适应算法能够较好地利用空闲分区,但分配时间较长。

最坏适应算法分配时间最长,但可以减少碎片的产生。

六、实验总结通过本次实验,我了解了可变分区存储管理的原理和方法,掌握了可变分区分配和回收的算法。

在实践中,我发现不同的分区算法适用于不同的场景,需要根据实际情况进行选择。

此外,对于空闲分区的合并也是提高存储利用率的重要步骤,需要重视。

最后,通过本次实验,我对存储管理的概念和原理有了更深入的理解,并且掌握了实现可变分区存储管理的方法和技巧。

主存储器空间分配和回收实验报告

主存储器空间分配和回收实验报告

软件学院计算机课程实验报告册课程名称计算机操作系统实验学期2011 年至2012 年第 2 学期学生所在院(系)软件学院年级11级专业班级软件工程1 班学生姓名朱水云学号**********指导教师陈自刚实验最终成绩软件学院实验室制2012 年4月0 5k 10k 14k 26k 32k128k 实验报告( 6 )实验名称:主存储器空间的分配和回收一、实验目的及要求:一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。

当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。

当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。

主存的分配和回收的实现虽与主存储器的管理方式有关的,通过本实验帮助学生理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。

二、实验内容与分析设计:本实验模拟在两种存储管理方式下的主存分配和回收。

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

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

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

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

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

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

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

操作系统实验——分区式存储管理算法

操作系统实验——分区式存储管理算法

河南农业大学——操作系统实验报告实验题目 : 可变分区内存分配与回收 学 院 : 理学院 班 级 : 10信安三班 学 号 : 1008105072 姓 名 : 高凯强一、课程设计目的了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。

通过这次实验,加深对内存管理的认识,进一步掌握内存的分配、回收算法的思想。

二、课程设计内容用C 语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程alloc()和回收过程free()。

其中,空闲分区通过空闲分区链来管理;在进行内存分配时,系统优先使用空闲区低端的空间。

假设初始状态下,可用的内存空间为640KB ,其中操作系统占用64KB ,并有下列的请求序列:作业1申请130KB 作业2申请60KB 作业3申请100KB作业2释放60KB 作业4申请200KB 作业3释放100KB作业1释放130KB作业5申请140KB作业6申请60KB作业7申请50KB作业6释放60KB请分别采用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况。

三、设计思路:整体思路:可变分区管理方式将内存除操作系统占用区域外的空间看做一个大的空闲区。

当作业要求装入内存时,根据作业需要内存空间的大小查询内存中的各个空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区。

如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

设计所才用的算法:采用最优适应算法,每次为作业分配内存时,总是把既能满足要求、又是最小的空闲分区分配给作业。

但最优适应算法容易出现找到的一个分区可能只比作业所需求的长度略大一点的情行,这时,空闲区分割后剩下的空闲区就很小以致很难再使用,降低了内存的使用率。

内存的分配和回收分区链实验报告按照这个内容来完成

内存的分配和回收分区链实验报告按照这个内容来完成

一、实验目的理解分区式存储管理的基本原理,熟悉分区分配和回收算法。

即理解在不同的存储管理方式下,如何实现主存空间的分配与回收;并掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、设备与环境1. 硬件设备:PC机一台2. 软件环境:安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如VC \VC++\Java 等编程语言环境。

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

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

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

A、主存空间分配(1)首次适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足要求的空闲区,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

(2)最佳适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中(3)最坏适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

B、主存空间回收当一个作业执行完成撤离时,作业所占的分区应该归还给系统。

主存空间的分配与回收

主存空间的分配与回收

操作系统实验报告实验三:主存空间的分配与回收实验题目采用可变式分区管理,使用首次或最佳适应算法实现主存的分配与回收实验内容主存是中央处理机能直接存取指令和数据的存储器。

能否合理而有效地使用主存,在很大程度上将影响到整个计算机系统的性能。

本实验采用可变式分区管理,使用首次或最佳适应算法实现主存空间的分配与回收。

要求采用分区说明表进行。

实验目的通过本次实验,帮助学生理解在可变式分区管理方式下,如何实现主存空间的分配与回收。

提示:(1) 可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。

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

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

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

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

0 10K 20K 45K 65K 110K 256K 操作系统(10KB)作业1 (10KB )作业4 (25KB )空闲区1 (20KB)作业2 (45KB )空闲区2 ( 146KB)表1空闲区说明表闲区大小。

状态栏未分配指该栏目是记录的有效空闲区,空表目指没有登记信息。

由于分区个数不定,所以空闲区说明表中应有足够的空表目项,否则造成溢出,无法登记。

同样,再设一个已分配区表,记录作业或进城的主存占用情况。

(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需求量,这时应该将空闲区一分为二。

一个分给作业,另一个仍作为空闲区留在空闲区表中。

为了尽量减少由于分割造成的碎片,尽可能分配低地址部分的空闲区,将较大空闲区留在高地址端,以利于大作业的装入。

为此在空闲区表中,按空闲区首地址从低到高进行登记。

为了便于快速查找,要不断地对表格进行紧缩,即让“空表目”项留在表的后部。

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

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

可变分区存储管理方式的内存分配和回收第一篇:可变分区存储管理方式的内存分配和回收#include//定义输入/输出函数#include//数据流输入/输出#include//字符串处理#include//参数化输入/输出const int MJ=10;//假定系统允许的最大作业数量为10typedef 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<cin>>fn;if((fp=fopen(fn,“r”))==NULL){ 其意义是在当前目录下打开文件file a,只允许进行“读”操作,并使fp指向该文件cout<}else{while(!feof(fp)){fscanf(fp,“%d,%d”,&frees[free_quantity].address,&frees[free_quantity].length);free_quantity++;fscanf(文件指针,格式字符串,输入表列);}return 1;}return 0;}void sort(){int i,j,p;for(i=0;ip=i;for(j=i+1;jif(frees[j].addressp=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}void view(){int i;cout<cout<for(i=0;icout.setf(2); cout.width(12); cout<cout.width(10); cout<cout.width(8); cout<}cout<cout<for(i=0;icout.setf(2); cout.width(12); cout<cout.width(10); cout<cout.width(8); cout<}}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;iif(frees[i].length>=job_length){flag=1;}}if(flag==0){//未找到空闲区,返回cout<}else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){//找到可用空闲区,开始分配t=1;}i++;}i--;occupys[occupy_quantity].address=frees[i].address;//修改已分配区表strcpy(occupys[occupy_quantity].tag,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;jfrees[j]=frees[j+1];}free_quantity--;cout<}}}void reclaim()//回收作业所占的内存空间{char job_name[20];int i,j,flag,p=0;int address;int length;//寻找已分分区表中对应的登记项cout<cin>>job_name;flag=-1;for(i=0;iif(!strcmp(occupys[i].tag,job_name)){flag=i;address=occupys[i].address;length=occupys[i].length;}}if(flag==-1){ //在已分分区表中找不到作业cout<}else{//修改空闲区表,加入空闲表for(i=0;iif((frees[i].address+frees[i].length)==address){ if(((i+1)for(j=i+1;jfrees[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++;}//删除分配表中的该作业for(i=flag;ioccupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int flag=0;int t=1;int chioce=0;int i;for(i=0;ifrees[i].address=-1;//空闲区表初始化frees[i].length=0;strcpy(frees[i].tag,“free”);occupys[i].address=-1;//已分分区表初始化occupys[i].length=0;strcpy(occupys[i].tag,“");}free_quantity=0;occupy_quantity=0;flag=read();while(flag==1){sort();cout<cin>>chioce;switch(chioce){case 0:flag=0;break;case 1:ear();break;case 2:reclaim();break;case 3:view();break;default:cout<}}}第二篇:可变分区存储管理方式的内存分配和回收实验报告一.实验目的通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。

可变分区存储管理方式的内存分配和回收实验报告(最优算法)

可变分区存储管理方式的内存分配和回收实验报告(最优算法)

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

二.实验内容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]; // 安闲区表第二,在设计的数据表格基础上设计内存分派。

实验报告三 可变分区内存管理

实验报告三 可变分区内存管理

实验三可变分区内存管理班级:网络工程081 学号:0813072013 姓名:刘国画实验日期:2010.11.18实验内容可变分区内存管理。

实验目的(1)体会可变分区内存管理方案。

(2)掌握此方案的内存分配过程、内存回收过程和紧凑算法的实现的实现。

实验目标:编制一个程序模拟实现可变分区内存管理。

实验时,假设系统内存容量为100KB。

分配时使用my_malloc(i, j)函数实现,作业释放内存时使用my_free(handle)函数实现,内存情况输出用my_memlist( )实现。

实验步骤:1.编写主界面,界面上有三个选项:分配内存、回收内存、查看内存。

选择分配内存时,要求输入作业的进程号和作业长度,然后使用my_malloc分配内存,报告内存分配结果。

回收内存时要求输入进程号,使用my_free实现回收。

查看内存时,使用my_memlist实现输出内存使用情况和空闲情况。

2.编写my_malloc(i, j)函数,实现进程i申请j KB内存,要求程序判断是否能分配,如果能分配,要把分配的首地址handle输出到屏幕上。

不能分配输出字符串“NULL”。

要考虑不能简单分配时,是否符合紧凑的条件,如符合则采用紧凑技术。

然后再分配。

分配时可采用最佳适应算法。

3.编写my_free(handle)函数,释放首地址为handle的内存块。

释放成功返回Success,否则返回Failure。

4.编写my_memlist( )函数,要求输出内存使用情况和空闲情况。

5.内存情况输出的格式为:ID Address Len Process其中:ID:内存分区号Address:该分区的首地址Len:分区长度Process:如果使用,则为使用的进程号,否则为NULL实验设计数据结构设计:可变分区管理方式预先不将内存划分为几个区域,而是将内存除操作系统占用区域外的空间看做一个大的空闲区。

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

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告

计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号: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表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。

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

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

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

内存的分配与回收实验报告(最先适应法)

内存的分配与回收实验报告(最先适应法)

代码实现如下:#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define n 64 //定义内存的大小int a[n],count=0;//数组a用来保存内存使用状况1为已分配0为未分配,count用来记name数组中元素个数char name[n];//已分配内存的名称(字符类型)typedef struct linknode{char pid;int start;int length;struct linknode *left,*right;}de_node; //进程节点结构体定义//head1表示未分配内存队列头指针,head2便是已分配进程队列头指针de_node *head1,*head2=NULL;struct linknode* creat()//创建一个进程节点{int len,flag1=1;//用于表示进程是否可以创建char id;struct linknode* p;p = (de_node *)malloc(sizeof(de_node));//试图在系统内存中开辟空间创建一个进程if (p==NULL) //p为空,说明系统没有可用内存用于创建此模拟进程{ printf("系统没有足够的内存可供使用!\n");//输出return(NULL);//返回空指针}printf("请输入进程id(字符类型)和长度:");//为进程输入id和分配的长度scanf("%c %d",&id,&len);fflush(stdin);//清除输入缓存if((id>='a'&&id<='z'||id>='A'&&id<='Z')&&(len>0)){for(int i=0;i<count;i++)//判断输入的进程名,如果已使用,返回空指针,并释放p指针if(name[i]==id){printf("此名称进程已存在!!");flag1=0;//标志位为0,表示下面对p指向内容不做修改free(p);return NULL;}if(len==0) {//如果输入要分配的进程长度为0,释放p,返回空指针printf("输入长度为0!\n");free(p);return(NULL);}if(flag1){//标志位1,可以对p指向内容进行修改p->pid=id; //idp->start=0; //初始开始内存位置,在以后会修改p->length=len;//长度p->left=NULL;//左指针p->right=NULL;//右指针name[count++]=id;//将id存入数组,count自加return(p);}//返回创建的进程的地址}else {printf("输入进程格式有误\n");free(p);return (NULL);}}//分配内存空间void distribute(de_node *p){ de_node *q=head1,*temp;int flag=0;do{//do_while循法//判断当前指向的内存空间的长度是否满足p所申请的长度,大于就分配if(q->length>=p->length) {p->start=q->start;//把进程的内存开始地址指向内存的可用开始地址处q->start+=p->length;//可用地址起始改变q->length-=p->length;//可用内存长度修改for(int i=p->start;i<p->start+p->length;i++)//将已分配的内存空间全部置1 a[i]=1;flag=1;//表示内存可分配//队列不止一个进程,第一个满足条件,并且刚好分配完,修改指针指向if(q->length==0&&q->right!=q) { if(q==head1)//如果第一个满足,修改头指针指向head1=q->right;q->left->right=q->right;q->right->left=q->left;free(q);//把这个已分配完的空间指针释放}}if(flag==1)//已做完处理直接跳出循环break;if(flag==0)//当前指向的内存不满足,指向下一个,继续判断是否满足q=q->right;}while(q!=head1);//搜索一遍可用内存序列if(flag==0){//没有可用的内存printf("没有满足的内存!\n");count--;//由于创建时加1,但在分配内存时失败,把1又减掉free(p);//把这个未分配到内存的进程释放}if(flag==1){//表示上面已分配好内存,并已修改内存链表,下面修改已分配内存的进程队列temp=head2;//把已分配内存的进程队列赋值给临时指针if(temp==NULL)//如果还还没有存在的任何的进程,说明当前是第一个{ head2=p;//让头指针指向第一个进程p->left=p;//双向队列第一个左右指针都指向自己p->right=p;//双向队列第一个左右指针都指向自己}else if(temp!=NULL){//已存在队列,把当前直接链到第一个,与上面的区别是指针指向head2=p;//让头指针指向p指向的进程p->left=temp->left;//p进程左边为原来第一个的左边p->right=temp;//p进程右边指向第一个temp->left->right=p;//原来第一个的左边为ptemp->left=p;//原来第一个的左边的进程为p}}}//对进程的回收void reclaim(){ char id;int flag=0;de_node *q=head2,*p=head1;if(head2==NULL)//表示当前没有进程{ printf("已没有进程!\n");}else {//已分配内存队列如果不为空printf("输入要回收的进程id:");//输入要回收进程的idscanf("%c",&id);fflush(stdin);for(int i=0;i<count;i++)//双重循环把要回收的进程找出来,并把记录的id去掉if(name[i]==id){//判断当前的进程是否满足要求for(int j=i;j<count;j++)name[j]=name[j+1];//向前覆盖name[j+1]=NULL;//置空count--;//减一}//判断是否总共只有一个进程且是够刚好也满足条件if(q->pid==id&&q->right==q&&head2==q){ head2=NULL;//把已分配队列直接置空flag=1;//表示找到满足条件的进程}if(flag==0){//上面的都没找到do{if(q->pid==id){//如果找到if(q==head2)head2=q->right;q->left->right=q->right;//修改指针指向q->right->left=q->left;flag=1;break;}else q=q->right;}while(q!=head2);}//如果找到或是遍历一遍结束if(flag==0) printf("没有此进程号!!!\n");//没有找到满足的进程if(flag==1){//表示找到了for(int i=q->start;i<q->start+q->length;i++)//释放占有的内存a[i]=0;//接下来修改可用内存的队列,while(q->start>p->start&&p->right!=head1){//从第一个开始找到回收回来的内存开始地址大的那个队列p=p->right;}if(p==head1)//表示比第一个的开始还小,那么就要修改头地址head1=q;//其他情况不用修改头地址,只需找到应该的位置,把此进程插进去q->left=p->left;//修改指针的指向q->right=p;p->left->right=q;p->left=q;if(q->start+q->length==p->start)//可以与后面合并的情况{ q->length+=p->length;//修改指针的指向p->right->left=q;q->right=p->right;free(p);}if(q->left->start+q->left->length==q->start)//可以与前面合并的情况{ q->left->length+=q->length;//修改指针的指向q->left->right=q->right;q->right->left=q->left;free(q);}}}}//打印输出void print(){ de_node *q=head2,*p=head1;if(count==0)printf("没有进程占有内存。

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

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

(实验3)在可变分区管理方式下采用最先适应算法实现主存分配与回收

(实验3)在可变分区管理方式下采用最先适应算法实现主存分配与回收

实验3 内存管理一、实验内容选择一种算法在可变分区管理方式下对内存进行管理 二、实验目的掌握可变分区内存管理方式,能熟练运用内存管理的各种算法对内存进行分配和回收。

三、实验题目在可变分区管理方式下采用最先适应算法实现主存分配与回收 [提示]:可变分区方式是按作业需要的主存空间大小来分割分区的。

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

随着作业的装入、撤离,主为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:第一栏 第二栏其中,起址——指出一个空闲区的主存起始地址。

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

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

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

上述的这张说明表的登记情况是按提示(1)中的例所装入的三个作业占用的主存区域后填写的。

(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。

为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。

为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。

为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。

(3) 采用最先适应算法(顺序分配算法)分配主存空间。

天津理工大学_操作系统_存储器的分配与回收算法实现_实验报告

天津理工大学_操作系统_存储器的分配与回收算法实现_实验报告

实验报告学院(系)名称:计算机与通信工程学院【实验过程记录(源程序、测试用例、测试结果及心得体会等)】源程序:MemoryBlock.java://内存块类,包含各种操作public class MemoryBlock {static final int BLOCK_SIZE = 4096;private int baseBlock; //内存块基地址private int blockNum; //大小private boolean inUse; //是否已分配private MemoryBlock prev, next;public MemoryBlock(int blockNum) {this.baseBlock = 0;this.blockNum = blockNum;inUse = false;prev = null;next = null;}public MemoryBlock(int base, int blockNum) {this.baseBlock = base;this.blockNum = blockNum;inUse = false;prev = null;next = null;}public int getBlockNum() {return blockNum;}public void setBlockNum(int blockNum) {this.blockNum = blockNum;}public MemoryBlock getPrev() {return prev;}public void setPrev(MemoryBlock prev) {this.prev = prev;public MemoryBlock getNext() {return next;}public void setNext(MemoryBlock next) {this.next = next;}public boolean inUse() {return inUse;}public void setUse() {inUse = true;}public void free() {inUse = false;}public int getBaseBlock() {return baseBlock;}public void setBaseBlock(int baseBlock) { this.baseBlock = baseBlock;}//分配内存块,如果可分配,则返回剩余内存块public MemoryBlock allocate(int blockNum) { if(this.blockNum - blockNum>0) {int newBase = baseBlock + blockNum;int newBlock = this.blockNum-blockNum;this.blockNum = blockNum;setUse();return new MemoryBlock(newBase, newBlock);}else if(this.blockNum - blockNum ==0) {this.blockNum = 0;}return null;}//判断内存块是否能合并public boolean merge(MemoryBlock memBlock) {if(baseBlock+blockNum==memBlock.getBaseBlock()) {setBlockNum(blockNum+memBlock.blockNum);memBlock.setBaseBlock(0);memBlock.setBlockNum(0);return true;}elsereturn false;}@Overridepublic String toString() {String inUse = null;if(inUse())inUse = "已分配";else inUse = "未分配";return"内存块 [基地址=" + baseBlock + ", 大小=" + blockNum +", " + inUse + "]";}}MemoryTable.java://虚类MemTable,提供内存链表的各种基本方法public abstract class MemoryTable {//MemoryBlock链表表头protected MemoryBlock memList;public MemoryTable(int blockNum) {memList = new MemoryBlock(0, blockNum);}//把newBlock插入到memBlock前面public void insertBefore(MemoryBlock memBlock, MemoryBlock newBlock){if(memBlock.getPrev() != null)memBlock.getPrev().setNext(newBlock);if(memList == memBlock)memList = newBlock;newBlock.setPrev(memBlock.getPrev());newBlock.setNext(memBlock);memBlock.setPrev(newBlock);}//在memBlock后插入newBlockpublic void insert(MemoryBlock memBlock, MemoryBlock newBlock) { if(memBlock.getNext() != null)memBlock.getNext().setPrev(newBlock);newBlock.setNext(memBlock.getNext());memBlock.setNext(newBlock);newBlock.setPrev(memBlock);}//删除块的连接关系,但不释放块public void remove(MemoryBlock memBlock) {if(memBlock == memList)memList = memBlock.getNext();if(memBlock.getNext()!=null)memBlock.getNext().setPrev(memBlock.getPrev());if(memBlock.getPrev()!=null)memBlock.getPrev().setNext(memBlock.getNext());}public void print() {MemoryBlock memBlock = memList;int i=0;while(memBlock != null) {System.out.print(i+" ");System.out.println(memBlock);i++;memBlock = memBlock.getNext();}}//合并邻接的空闲内存public void merge(MemoryBlock newBlock) {MemoryBlock memBlock = memList;while(memBlock != null) {if(!memBlock.inUse()) {if(memBlock.merge(newBlock)) {memBlock.setBlockNum( memBlock.getBlockNum() +newBlock.getBlockNum());remove(newBlock);break;}if(newBlock.merge(memBlock)) {newBlock.setBlockNum( newBlock.getBlockNum() + memBlock.getBlockNum());break;}}memBlock = memBlock.getNext();}}//分配内存(抽象函数)public abstract boolean allocate(int blockNum);//释放内存(抽象函数)public abstract boolean free(int baseBlock);}FirstFit.java:public class FirstFit extends MemoryTable{public FirstFit(int blockNum) {super(blockNum);}@Overridepublic boolean allocate(int blockNum) {MemoryBlock memBlock = memList;while(memBlock!=null) {if(!memBlock.inUse()) {if(memBlock.getBlockNum()>blockNum) {MemoryBlock newBlock = memBlock.allocate(blockNum);insert(memBlock, newBlock);return true;}else if(memBlock.getBlockNum()==blockNum) {memBlock.setUse();}}memBlock = memBlock.getNext();}return false;}//分配内存(类内使用)void freeMemory(MemoryBlock freeBlock) {MemoryBlock prev = freeBlock.getPrev();MemoryBlock next = freeBlock.getNext();freeBlock.free();while(!prev.inUse() && (prev.merge(freeBlock))) {prev.setBlockNum( prev.getBlockNum() +freeBlock.getBlockNum());remove(freeBlock);freeBlock = prev;if(freeBlock.getPrev()!=null)prev = freeBlock.getPrev();else return;}}if(freeBlock.getNext()!=null) {while(!next.inUse() && (freeBlock.merge(next))) {freeBlock.setBlockNum ( next.getBlockNum() +freeBlock.getBlockNum());remove(next);freeBlock = next;if(freeBlock.getNext()!=null)next = freeBlock.getNext();else return;}}}@Overridepublic boolean free(int baseBlock) {MemoryBlock memBlock = memList;while(memBlock != null) {if(memBlock.getBaseBlock() == baseBlock) {freeMemory(memBlock);return true;}memBlock = memBlock.getNext();}return false;}}BestFit.java:public class BestFit extends MemoryTable {private MemoryBlock usedMemory;public BestFit(int blockNum) {super(blockNum);usedMemory = null;}@Overridepublic boolean allocate(int blockNum) {MemoryBlock memBlock = memList;MemoryBlock minBlock = null;for(;memBlock!=null; memBlock = memBlock.getNext()) { if(!memBlock.inUse()&&(memBlock.getBlockNum()>=blockNum)) { minBlock = memBlock;break;}}if(minBlock != null) {remove(minBlock);if(minBlock.getBlockNum()!=blockNum) {MemoryBlock newBlock = minBlock.allocate(blockNum);insertUnused(newBlock);}insertUsed(minBlock);return true;}elsereturn false;}boolean freeMemory(MemoryBlock freeBlock) {if(freeBlock != null) {freeBlock.free();removeUsed(freeBlock);insertUnused(freeBlock);return true;}return false;}@Overridepublic boolean free(int baseBlock) {MemoryBlock memBlock = usedMemory;while(memBlock != null) {if(memBlock.getBaseBlock() == baseBlock) {freeMemory(memBlock);merge(memBlock);return true;}memBlock = memBlock.getNext();return false;}//在已分配链表删除public void removeUsed(MemoryBlock memBlock) {if(memBlock == usedMemory)usedMemory = memBlock.getNext();if(memBlock.getNext()!=null)memBlock.getNext().setPrev(memBlock.getPrev());if(memBlock.getPrev()!=null)memBlock.getPrev().setNext(memBlock.getNext());}//插入未分配链表void insertUnused(MemoryBlock newBlock) {if(memList == null)memList = newBlock;else {MemoryBlock memBlock = memList;MemoryBlock preBlock = null;while(memBlock!=null) {if(newBlock.getBlockNum()<=memBlock.getBlockNum()) { insertBefore(memBlock, newBlock);return;}preBlock = memBlock;memBlock = memBlock.getNext();}insert(preBlock, newBlock);}}//插入已分配链表void insertUsed(MemoryBlock newBlock) {if(usedMemory == null)usedMemory = newBlock;else {MemoryBlock memBlock = usedMemory;while(memBlock.getNext() != null)memBlock = memBlock.getNext();memBlock.setNext(newBlock);newBlock.setPrev(memBlock);}}public void print() {super.print();MemoryBlock memBlock = usedMemory;int i=0;while(memBlock != null) {System.out.print(i+" ");System.out.println(memBlock);i++;memBlock = memBlock.getNext();}}}WorstFit.java:public class WorstFit extends MemoryTable {//已分配链表private MemoryBlock usedMemory;public WorstFit(int blockNum) {super(blockNum);usedMemory = null;}@Overridepublic boolean allocate(int blockNum) {MemoryBlock maxBlock = memList;if(maxBlock.getBlockNum()<blockNum)return false;remove(maxBlock);if(maxBlock.getBlockNum()!=blockNum) {MemoryBlock newBlock = maxBlock.allocate(blockNum);insertUnused(newBlock);}insertUsed(maxBlock);return true;}boolean freeMemory(MemoryBlock freeBlock) {if(freeBlock != null) {freeBlock.free();removeUsed(freeBlock);insertUnused(freeBlock);}return false;}@Overridepublic boolean free(int baseBlock) {//已分配链表MemoryBlock memBlock = usedMemory;while(memBlock != null) {if(memBlock.getBaseBlock() == baseBlock) {freeMemory(memBlock);merge(memBlock);return true;}memBlock = memBlock.getNext();}return false;}public void removeUsed(MemoryBlock memBlock) {if(memBlock == usedMemory)usedMemory = memBlock.getNext();if(memBlock.getNext()!=null)memBlock.getNext().setPrev(memBlock.getPrev());if(memBlock.getPrev()!=null)memBlock.getPrev().setNext(memBlock.getNext());}void insertUnused(MemoryBlock newBlock) {if(memList == null)memList = newBlock;else {MemoryBlock memBlock = memList;MemoryBlock preBlock = null;while(memBlock!=null) {if(newBlock.getBlockNum()>=memBlock.getBlockNum()) { insertBefore(memBlock, newBlock);return;}preBlock = memBlock;memBlock = memBlock.getNext();}insert(preBlock, newBlock);}}void insertUsed(MemoryBlock newBlock) {if(usedMemory == null)usedMemory = newBlock;else {MemoryBlock memBlock = usedMemory;while(memBlock.getNext() != null)memBlock = memBlock.getNext();memBlock.setNext(newBlock);newBlock.setPrev(memBlock);}}public void print() {super.print();MemoryBlock memBlock = usedMemory;int i=0;while(memBlock != null) {System.out.print(i+" ");System.out.println(memBlock);i++;memBlock = memBlock.getNext();}}}测试用例:Main.java:public class Main {public static void main(String[] args) {testFirstFit();System.out.println();testBestFit();System.out.println();testWorstFit();}public static void testFirstFit() {MemoryTable mem = new FirstFit(1024);System.out.println("测试首次适应法:");mem.allocate(512);mem.allocate(256);mem.allocate(128);mem.print();mem.free(512);mem.free(768);mem.print();}public static void testBestFit() {MemoryTable mem = new BestFit(1024);System.out.println("测试最佳适应法:");mem.allocate(1);mem.allocate(2);mem.allocate(3);mem.print();mem.free(0);mem.free(1);mem.print();}public static void testWorstFit() {MemoryTable mem = new WorstFit(1024);System.out.println("测试最坏适应法:");mem.allocate(1);mem.allocate(2);mem.allocate(3);mem.print();mem.free(0);mem.free(3);mem.print();}}测试结果:测试首次适应法:分配 512 内存分配 256 内存分配 128 内存内存单元:0 内存块 [基地址=0, 大小=512, 已分配]1 内存块 [基地址=512, 大小=256, 已分配]2 内存块 [基地址=768, 大小=128, 已分配]3 内存块 [基地址=896, 大小=128, 未分配]释放 512 处内存释放 768 处内存内存单元:0 内存块 [基地址=0, 大小=512, 已分配]1 内存块 [基地址=512, 大小=512, 未分配]测试最佳适应法:分配 1 内存分配 2 内存分配 3 内存内存单元:0 内存块 [基地址=6, 大小=1018, 未分配]0 内存块 [基地址=0, 大小=1, 已分配]1 内存块 [基地址=1, 大小=2, 已分配]2 内存块 [基地址=3, 大小=3, 已分配]释放 0 处内存释放 1 处内存内存单元:0 内存块 [基地址=0, 大小=3, 未分配]1 内存块 [基地址=6, 大小=1018, 未分配]0 内存块 [基地址=3, 大小=3, 已分配]测试最坏适应法:分配 1 内存分配 2 内存分配 3 内存内存单元:0 内存块 [基地址=6, 大小=1018, 未分配]0 内存块 [基地址=0, 大小=1, 已分配]1 内存块 [基地址=1, 大小=2, 已分配]2 内存块 [基地址=3, 大小=3, 已分配]释放 0 处内存释放 3 处内存内存单元:0 内存块 [基地址=3, 大小=1021, 未分配]1 内存块 [基地址=0, 大小=1, 未分配]0 内存块 [基地址=1, 大小=2, 已分配]心得体会:1.使用类来进行一些方法的重用2.释放内存时,根据不同的分配方法进行相邻的内存合并3.链表应根据具体情况优化从而简化代码。

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

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

操作系统实验报告可变分区存储管理方式的内存分配回收可变分区存储管理方式是一种常见的内存分配和回收策略,通过将内存分成若干大小不等的分区,分配给不同大小的进程使用。

本文将对可变分区存储管理方式的内存分配和回收进行详细介绍。

首先,可变分区存储管理方式需要对内存进行划分,将内存分成若干个大小不等的分区。

这些分区可以是固定大小的,也可以是可变大小的。

当进程申请内存时,系统会根据申请内存的大小来选择一个合适大小的分区进行分配。

分配时分为两种情况:首次适应和最佳适应。

首次适应算法是指从内存的起始位置开始遍历分区,找到第一个能满足进程要求的分区进行分配。

这种算法的优点是找到满足条件的分区速度较快,缺点是容易造成较大的内存碎片。

最佳适应算法是指通过遍历整个内存,找到一个大小最接近进程要求的分区进行分配。

这种算法的优点是能够减小内存碎片的产生,但是分配速度较慢。

当进程结束时,需要回收其占用的内存。

对于可变分区存储管理方式,在回收内存时出现了两种情况:内部碎片和外部碎片。

内部碎片是指分配给进程的分区中,有一部分空闲内存无法被其他进程利用。

这是因为当一些进程需要分配内存时,分配的大小可能大于其实际需要的大小,导致分区中留下了空余空间。

解决内部碎片的方法是动态地调整分区的大小,使其能够更好地适应进程的大小需求。

外部碎片是指存储空闲的分区之间的一些不可利用的内存。

当进程需要分配内存时,可能没有一个分区能满足其大小需求,导致无法分配内存。

解决外部碎片的方法是内存紧缩和分区合并。

内存紧缩是指将内存中的进程向一端移动,使剩余的空闲内存空间连在一起。

这样可以使得所有的空闲内存空间都可以被利用,减少外部碎片的产生。

分区合并是指将不连续的空闲分区进行合并,形成更大的连续空闲分区。

这样可以提供给大型进程使用,减少外部碎片的产生。

综上所述,可变分区存储管理方式的内存分配和回收是一个动态的过程,需要根据进程的需求进行灵活地管理。

它可以通过首次适应或最佳适应算法选择合适的分区进行内存分配,通过动态调整分区大小解决内部碎片问题,并通过内存紧缩和分区合并减少外部碎片的产生。

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

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

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

二.实验内容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]; //空闲区表第二,在设计的数据表格基础上设计内存分配。

装入一个作业时,从空闲区表中查找满足作业长度的未分配区,如大于作业,空闲区划分成两个分区,一个给作业,一个成为小空闲分区。

实验中内存分配的算法采用“最优适应”算法,即选择一个能满足要求的最小空闲分区。

第三,在设计的数据表格基础上设计内存回收问题。

内存回收时若相邻有空闲分区则合并空闲区,修改空闲区表。

四、参考程序#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和长度LS=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].flag+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); //回收内存空间。

相关文档
最新文档