天津理工大学_操作系统_存储器的分配与回收算法实现_实验报告
实验报告二主存空间的分配和回收
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;
存储器管理实验实验报告
存储器管理实验实验报告一、实验目的存储器管理是操作系统的重要组成部分,本次实验的目的在于深入理解存储器管理的基本原理和方法,通过实际操作和观察,掌握存储器分配与回收的算法,以及页面置换算法的实现和性能评估。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验内容与步骤(一)存储器分配与回收算法实现1、首次适应算法(1)原理:从空闲分区链的首地址开始查找,找到第一个满足需求的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态(已分配或空闲)。
当有分配请求时,从链表头部开始遍历,找到第一个大小满足需求的空闲分区。
将该分区进行分割,一部分分配给请求,剩余部分仍作为空闲分区留在链表中。
若找不到满足需求的空闲分区,则返回分配失败。
2、最佳适应算法(1)原理:从空闲分区链中选择与需求大小最接近的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。
当有分配请求时,遍历整个链表,计算每个空闲分区与需求大小的差值。
选择差值最小的空闲分区进行分配,若有多个差值相同且最小的分区,选择其中起始地址最小的分区。
对选中的分区进行分割和处理,与首次适应算法类似。
3、最坏适应算法(1)原理:选择空闲分区链中最大的空闲分区进行分配。
(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。
当有分配请求时,遍历链表,找到最大的空闲分区。
对该分区进行分配和处理。
(二)页面置换算法实现1、先进先出(FIFO)页面置换算法(1)原理:选择在内存中驻留时间最久的页面进行置换。
(2)实现步骤:建立页面访问序列。
为每个页面设置一个进入内存的时间戳。
当发生缺页中断时,选择时间戳最早的页面进行置换。
2、最近最久未使用(LRU)页面置换算法(1)原理:选择最近一段时间内最长时间未被访问的页面进行置换。
实现内存分配实验报告(3篇)
第1篇一、实验目的1. 理解操作系统内存分配的基本原理和常用算法。
2. 掌握动态分区分配方式中的数据结构和分配算法。
3. 通过编写程序,实现内存分配和回收功能。
二、实验环境1. 操作系统:Linux2. 编程语言:C语言3. 开发工具:GCC编译器三、实验原理1. 内存分配的基本原理操作系统内存分配是指操作系统根据程序运行需要,将物理内存分配给程序使用的过程。
内存分配算法主要包括以下几种:(1)首次适应算法(First Fit):从内存空间首部开始查找,找到第一个满足条件的空闲区域进行分配。
(2)最佳适应算法(Best Fit):在所有满足条件的空闲区域中,选择最小的空闲区域进行分配。
(3)最坏适应算法(Worst Fit):在所有满足条件的空闲区域中,选择最大的空闲区域进行分配。
2. 动态分区分配方式动态分区分配方式是指操作系统在程序运行过程中,根据需要动态地分配和回收内存空间。
动态分区分配方式包括以下几种:(1)固定分区分配:将内存划分为若干个固定大小的分区,程序运行时按需分配分区。
(2)可变分区分配:根据程序大小动态分配分区,分区大小可变。
(3)分页分配:将内存划分为若干个固定大小的页,程序运行时按需分配页。
四、实验内容1. 实现首次适应算法(1)创建空闲分区链表,记录空闲分区信息,包括分区起始地址、分区大小等。
(2)编写分配函数,实现首次适应算法,根据程序大小查找空闲分区,分配内存。
(3)编写回收函数,回收程序所占用的内存空间,更新空闲分区链表。
2. 实现最佳适应算法(1)创建空闲分区链表,记录空闲分区信息。
(2)编写分配函数,实现最佳适应算法,根据程序大小查找最佳空闲分区,分配内存。
(3)编写回收函数,回收程序所占用的内存空间,更新空闲分区链表。
3. 实验结果分析(1)通过实验,验证首次适应算法和最佳适应算法的正确性。
(2)对比两种算法在内存分配效率、外部碎片等方面的差异。
五、实验步骤1. 创建一个动态内存分配模拟程序,包括空闲分区链表、分配函数和回收函数。
实验二存储器的分配与回收算法实现
实验二存储器的分配与回收算法实现一、实验目的1.学习存储器的分配与回收算法;2.实现动态存储管理的相关算法。
二、实验原理在计算机系统中,存储器是一项重要的资源。
为了有效地利用存储器资源,需要设计合理的存储器管理算法来进行存储器的分配与回收。
常用的存储器管理算法有以下几种:1. 首次适应算法(First Fit):分配内存时从链表的头部开始查找第一个满足要求的空闲内存单元。
2. 最佳适应算法(Best Fit):分配内存时从整个链表中找到最小的满足要求的空闲内存单元。
3. 最坏适应算法(Worst Fit):分配内存时从整个链表中找到最大的满足要求的空闲内存单元。
4. 循环首次适应算法(Next Fit):分配内存时从上一次分配结束的位置开始查找第一个满足要求的空闲内存单元。
5. 最近最少使用策略(Least Recently Used, LRU):当内存不足时,将最近最久未使用的页面置换出去。
6.先进先出策略(FIFO):将最先进入缓冲区的页面置换出去。
三、实验步骤1.首先,我们需要定义一个数据结构来表示存储器块,该数据结构包含以下字段:-起始地址:表示该存储器块的起始地址;-大小:表示该存储器块的大小;-状态:表示该存储器块的使用状态(空闲/已分配);-下一存储器块地址:指向链表中下一个存储器块的地址。
2.然后,创建一个链表来表示存储器块的集合,链表的每个节点表示一个存储器块。
3. 实现首次适应算法(First Fit):-遍历链表,找到第一个大小大于等于所需内存的空闲存储器块;-将该存储器块标记为已分配,并更新链表中该存储器块的状态;-如果找不到满足要求的存储器块,则表示存储器不足,分配失败。
4. 实现最佳适应算法(Best Fit):-遍历链表,找到大小最小的满足要求的空闲存储器块;-将该存储器块标记为已分配,并更新链表中该存储器块的状态;-如果找不到满足要求的存储器块,则表示存储器不足,分配失败。
操作系统存储管理实验报告
操作系统存储管理实验报告一、实验目的本次实验的目的是通过编写一段程序,实现对内存的分配和回收操作,并验证算法的正确性和性能。
二、实验内容1.实现首次适应算法首次适应算法是一种动态分配的内存管理算法,通过从低地址往高地址内存块,找到第一个满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,根据需求大小找到第一个合适的空闲块,并在其前后设置相应的标志位;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
2.实现最佳适应算法最佳适应算法是一种动态分配的内存管理算法,通过整个内存空间,找到最小的满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,遍历整个内存空间,找到满足需求且大小最小的空闲块进行分配;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
三、实验结果1.首次适应算法经过测试,首次适应算法能够正确地进行内存的分配和回收操作,并且算法的性能良好。
尽管首次适应算法在分配过程中可能会产生碎片,但是由于它从低地址开始,可以在较短的时间内找到满足需求的空闲块。
在实际应用中,首次适应算法被广泛采用。
2.最佳适应算法经过测试,最佳适应算法能够正确地进行内存的分配和回收操作,并且算法的性能较好。
最佳适应算法会整个内存空间,找到大小最小的满足需求的空闲块。
因此,在分配过程中不会产生很多的碎片,但是算法的执行时间较长。
四、实验总结通过本次实验,我们成功地实现了首次适应算法和最佳适应算法,并对算法的正确性和性能进行了验证。
两种算法在内存的分配和回收过程中都表现出良好的性能,可广泛应用于实际场景中。
实验四操作系统存储管理实验报告
实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。
二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。
三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。
在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。
2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。
为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。
3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。
同样通过对空闲分区链表的排序和查找来实现。
(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。
在模拟过程中,使用一个队列来记录页面的进入顺序。
2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。
通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。
3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。
四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。
2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。
3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。
实验二:存储器的分配与回收算法实现
p1->size=SPACE;
p1->address=ORIGI;
p1->next=NULL;
head=p1;
return(head);
}
struct allocate *creatallocate(void)//建立已分配表
{
struct allocate *head;
int SPACE=100;//定义内存空间大小
int ORIGI=1;//定义内存起始地址
struct job//定义作业
{
int name;
int size;
int address;
};
struct idle//定义空闲区
{
int size;
int address;
struct idle *next;
实验报告
学院(系)名称:计算机与通信工程学院
姓名
刘俊杰
学号
20115542
专业
信息与计算科学
班级
2011级1班
实验项目
实验二:存储器的分配与回收算法实现
课程名称
操作系统
课程代码
0668036
实验时间
2013-11-273-4节
2013-11-297-8节
2013-12-43-4节
2013-12-6 7-8节
#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define LEN1 sizeof(struct job)//作业大小
#define LEN2 sizeof(struct idle)//空闲区单元大小
计算机操作系统内存分配实验报告
计算机操作系统内存分配实验报告⼀、实验⽬的熟悉主存的分配与回收。
理解在不同的存储管理⽅式下.如何实现主存空间的分配与回收。
掌握动态分区分配⽅式中的数据结构和分配算法及动态分区存储管理⽅式及其实现过程。
⼆、实验容和要求主存的分配和回收的实现是与主存储器的管理⽅式有关的。
所谓分配.就是解决多道作业或多进程如何共享主存空间的问题。
所谓回收.就是当作业运⾏完成时将作业或进程所占的主存空间归还给系统。
可变分区管理是指在处理作业过程中建⽴分区.使分区⼤⼩正好适合作业的需求.并且分区个数是可以调整的。
当要装⼊⼀个作业时.根据作业需要的主存量查看是否有⾜够的空闲空间.若有.则按需要量分割⼀个分区分配给该作业;若⽆.则作业不能装⼊.作业等待。
随着作业的装⼊、完成.主存空间被分成许多⼤⼤⼩⼩的分区.有的分区被作业占⽤.⽽有的分区是空闲的。
实验要求使⽤可变分区存储管理⽅式.分区分配中所⽤的数据结构采⽤空闲分区表和空闲分区链来进⾏.分区分配中所⽤的算法采⽤⾸次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。
同时.要求设计⼀个实⽤友好的⽤户界⾯.并显⽰分配与回收的过程。
同时要求设计⼀个实⽤友好的⽤户界⾯,并显⽰分配与回收的过程。
三、实验主要仪器设备和材料实验环境硬件环境: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运⾏完毕.释放所占存。
操作系统实验二存储管理动态分区分配及回收算法
实验二存储管理动态分区分配及回收算法一、实验目的通过分区管理实验,了解操作系统的基本概念,理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。
通过课程设计,我们可以进一步理解在计算机系统上运行的其它各类操作系统,并懂得在操作系统的支持下建立自己的应用系统。
二、实验要求本实验要求用一种结构化高级语言构造分区描述器,编制动态分区分配算法和回收算法模拟程序,并掌握分配算法的特点,提高编程技巧和对算法的理解和掌握。
三、实验过程1.准备(一)主程序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;然后,提示用户使用哪种分配算法,再提示是分配还是回收;分配时要求输入申请区的大小,回收时要求输入释放区的首址和大小。
(四)输出要求每执行一次,输出一次空闲区队列情况,内容包括:编号首址终址大小2.主要流程和源代码实验二源代码#include<stdio.h>#include<stdlib.h>#include<string.h>#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,r,add,rd;while(1){system("cls");printf("选择最先适应算法请输入F,选择最佳适应算法请输入B,退出程序请输入E\n\n"); printf("请输入你的选择:");scanf("%c",&chose);if(chose=='e'||chose=='E')exit(0);else{system("cls");while(1){if(chose=='f'||chose=='F')printf("最先适应算法(First-Fit)模拟:\n");if(chose=='b'||chose=='B')printf("最佳适应算法(Best-Fit)模拟:\n");printf("1.分配内存,2.回收内存,3.查看内存,4.返回\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();}四、实验结果五、实验总结通过这次课程设计我练习了用C语言写系统软件,对操作系统中可变分区存储管理有了更深刻的了解。
内存分配回收实验报告
一、实验目的通过本次实验,加深对内存分配与回收机制的理解,掌握内存分配算法和回收策略,并能够运用所学知识解决实际内存管理问题。
二、实验内容1. 确定内存空间分配表;2. 采用首次适应算法实现内存分配;3. 采用最佳适应算法实现内存分配;4. 采用最坏适应算法实现内存分配;5. 实现内存回收功能;6. 对比分析不同内存分配算法的优缺点。
三、实验步骤1. 创建一个内存空间模拟程序,用于演示内存分配与回收过程;2. 定义内存空间分配表,记录内存块的起始地址、大小和状态(空闲或占用);3. 实现首次适应算法,在内存空间分配表中查找第一个满足条件的空闲内存块,分配给请求者;4. 实现最佳适应算法,在内存空间分配表中查找最接近请求大小的空闲内存块,分配给请求者;5. 实现最坏适应算法,在内存空间分配表中查找最大的空闲内存块,分配给请求者;6. 实现内存回收功能,当内存块释放时,将其状态更新为空闲,并合并相邻的空闲内存块;7. 对比分析不同内存分配算法的优缺点,包括分配时间、内存碎片和内存利用率等方面。
四、实验结果与分析1. 首次适应算法:该算法按照内存空间分配表的顺序查找空闲内存块,优点是分配速度快,缺点是容易产生内存碎片,且内存利用率较低;2. 最佳适应算法:该算法查找最接近请求大小的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多;3. 最坏适应算法:该算法查找最大的空闲内存块,优点是内存利用率较高,缺点是分配速度较慢,且内存碎片较多。
五、实验结论通过本次实验,我们掌握了内存分配与回收的基本原理和算法,了解了不同内存分配算法的优缺点。
在实际应用中,我们需要根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。
六、实验心得1. 内存分配与回收是计算机系统中重要的组成部分,对系统性能有着重要影响;2. 熟练掌握内存分配算法和回收策略,有助于解决实际内存管理问题;3. 在实际应用中,应根据具体需求选择合适的内存分配算法,以优化内存管理,提高系统性能。
操作系统-内存分配与回收实验报告
操作系统-内存分配与回收实验报告本次实验是关于内存管理的实验,主要涉及内存分配和回收的操作。
本文将对实验过程和结果进行详细介绍。
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. 实验结果本次实验实现了一个简单的内存管理器,通过该内存管理器可以实现内存分配和回收的操作。
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告
计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告第一篇:计算机操作系统动态分区存储管理方式下的内存空间的分配与回收实验报告计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号: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表示未配};//空闲分区表第二,在设计的表格上进行内存分配λ首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。
主存空间的分配与及回收实验报告
主存空间的分配与及回收实验报告一、实验目的: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个整数。
内存的分配与回收实验报告(最先适应法)
代码实现如下:#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("没有进程占有内存。
天津理工大学_操作系统_存储器的分配与回收算法实现_实验报告
实验报告学院(系)名称:计算机与通信工程学院【实验过程记录(源程序、测试用例、测试结果及心得体会等)】源程序: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.链表应根据具体情况优化从而简化代码。
操作系统之内存分配与回收
操作系统实验内存的分配与回收实验报告一、实验题目:内存的分配与回收二、实验内容:利用可变分区的首次适应算法,模拟内存的分配与回收。
三、实验目的:掌握可变分区首次适应算法的原理以及其编程实现。
四、实验过程:1、基本思想:可变分区分配是根据进程的实际需求,动态地为之分配内存空间。
首次适应算法要求空闲空间链以地址递增的次序链接。
进行内存分配时,从链表头部开始依次检索,找到第一个不小于请求空间大小的空闲空间进行分配。
分配时需考虑碎片问题,若分配会导致碎片产生则将整块分区分配。
内存的回收需要考虑四种情况:⑴回收分区前后两个分区都空闲,则需要和前后两个分区合并;(2)回收分区只有前一分区空闲,则与前一分区合并;(3)回收分区只有后一分区空闲,则和后一分区合并;(4)回收分区独立,不考虑合并。
2、主要数据结构:struct FreeArea{ 链结点包含的数据:分区号、大小、起址、标记int ID;int size;long address;int sign;};struct Node { 双链表结点结构体:数据区、前向指针、后继指针FreeArea data;struct Node *prior;struct Node *next;}*DLinkList;3、输入、输出:输入: I.内存分配时由键盘输入分区ID和大小;II.内存回收时由键盘输入需要回收的分区ID;输出:输出内存的分配情况(按照地址从低到高)4、程序流程图:5、实验结果截屏:6、源程序代码:#include<iostream>using namespace std;#define Free 0 //空闲状态#define Busy 1 //已用状态#define PBusy 2 //碎片已用状态#define FINISH 1 //完成#define FINISH2 1 //完成#define ERROR 0 //出错#define memory 512 //最大内存空间为(单位:KB)#define min 10 //碎片最小值(单位:KB)typedef struct FreeArea//空闲链数据{int ID;int size;long address;int sign;};typedef struct Node//空闲连结构{FreeArea data;struct Node *prior;struct Node *next;}*DLinkList;DLinkList head; //头结点DLinkList tail; //尾结点int Create()//初始化{head=(DLinkList)malloc(sizeof(Node));//分配内存tail=(DLinkList)malloc(sizeof(Node));head->prior=NULL;head->next=tail;tail->prior=head;tail->next=NULL;tail->data.address=0;tail->data.size=memory;tail->data.ID=0;tail->data.sign=Free;return FINISH;}int FirstFit(int ID,int request)//首次适应算法{DLinkList temp=(DLinkList)malloc(sizeof(Node));//新建作业的结点temp->data.ID=ID;temp->data.size=request;temp->data.sign=Busy;Node *p=head;//插入指针Pwhile(p){if(p->data.sign==Free && p->data.size==request)//剩余大小恰好满足{p->data.sign=Busy;p->data.ID=ID;return FINISH;break;}else if(p->data.sign==Free&& p->data.size>request&& (p->data.size-request>min))//满足需求且有剩余且不产生碎片{temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.size;p->data.size=p->data.size-request;return FINISH;break;}else if(p->data.sign==Free&& p->data.size>request&& p->data.size-request<=min)//产生碎片时{p->data.sign=PBusy;p->data.ID=ID;return FINISH;break;}p=p->next;//若前面的分区都已分配,P指针后移}return ERROR;}int Allocate()//主存分配{int ID,request;cout<<"请输入作业所在分区号:";cin>>ID;cout<<"请输入分配的主存(单位:KB):";cin>>request;if(request<0 ||request==0){cout<<"分配的主存必须是正整数!"<<endl;return ERROR;}if(FirstFit(ID,request)==FINISH)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;}int Recycle(int ID)//回收{Node *p=head;while(p){if(p->data.ID==ID){p->data.sign=Free;//p->data.ID=Free;if((p->prior->data.sign==Free)&&(p->next->data.sign==Free))//与前后的空闲块相连{p->prior->data.size=p->prior->data.size+p->data.size+p->next->data.size;p->prior->next=p->next->next;if(p->next->next==NULL)//若p->next是最后一个结点{p->prior->data.ID=Free;p->next=NULL;}else{p->next->next->prior=p->prior;}break;}if(p->prior->data.sign==Free)//与前面的空闲块相连{p->prior->data.size+=p->data.size;p->prior->next=p->next;p->next->prior=p->prior;break;}if(p->next->data.sign==Free)//与后面的空闲块相连{p->data.size+=p->next->data.size;if(p->next->next==NULL)//若p->next是最后一个结点p->next=NULL;else{p->next->next->prior=p;p->next=p->next->next;}break;}break;}p=p->next;}cout<<"分区:"<<ID<<"回收成功"<<endl;return FINISH;}void show()//显示{cout<<" 主存分配情况\n";Node *p=head->next;while(p){cout<<"分区号:";if(p->data.ID==Free)cout<<"Free"<<endl;elsecout<<p->data.ID<<endl;cout<<"起始地址:"<<p->data.address;cout<<" 分区大小:"<<p->data.size<<" KB";cout<<" 状态:";if(p->data.sign==Free)cout<<"空闲"<<endl;else if(p->data.sign==PBusy)cout<<"碎片已分配"<<endl;elsecout<<"已分配"<<endl;p=p->next;}cout<<endl;}void main(){Create();int choice;int i;for(i=0;;i++){cout<<"请输入操作:";cout<<"1.分配内存 2.回收内存 3.显示主存0.退出";cout<<endl;cin>>choice;if(choice==1)// 分配内存Allocate();else if(choice==2)// 内存回收{ i nt ID;cout<<"请输入要释放的分区号:";cin>>ID;Recycle(ID);}else if(choice==3)//显示主存show();else if(choice==0)//退出break;else//非法输入{cout<<"输入有误!"<<endl;continue;}}}。
操作系统-存储器的分配与回收算法实现
操作系统实验报告存储器的分配与回收算法实现姓名:学号:班级:.一、实验名称及要求1、实验名称:存储器的分配与回收算法实现2、实验要求:学生应正确地设计有关的数据结构与各个功能模块,画出程序的流程图,编写程序,程序执行结果应正确。
3、实验方式:学生通过实验室的微机上机,实际调试程序。
4、实验环境:Windows操作系统环境下的个人微机C或C++程序设计语言二、实验内容1本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。
2采用最先适应法、最佳适应法、最坏适应法分配主存空间。
3当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。
若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。
4当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。
5运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。
三、实验程序#include <iostream.h>#include <malloc.h>#include <stdlib.h>typedef struct FreeLink{//定义自由链struct FreeLink *prior;char name;int start;int size;.bool flag;struct FreeLink *next;}* ptr,*head;head top;ptr p;void print(){//将内存分配情况打印到屏幕上p=top;cout<<"************************内存分配情况表************************"<<endl;cout<<"区号\t\t"<<"起始位置\t"<<"区间长度\t"<<"区间状态\t"<<endl;do{cout<<p->name<<"\t\t"<<p->start<<"\t\t"<<p->size<<"\t\t";if(p->flag==false){cout<<"空闲"<<endl;}else{cout<<"已占用"<<endl;}p=p->next;}while(p!=NULL);}void clear(){//结束操作时清空“内存”以备其他操作do{p=top;top=top->next;free(p);}while(top!=NULL);}void asc(ptr &p){//最佳适应法的内存分配函数int min;ptr op;FreeLink *fl=(FreeLink *)malloc(sizeof(FreeLink));cout<<"请输入要分配内存的进程名"<<endl;cin>>fl->name;cout<<"请输入要分配内存的大小"<<endl;cin>>fl->size;min=256;fl->flag=true;do{if(p->flag==false&&p->size<=min&&p->size>=fl->size){ min=p->size;op=p;}p=p->next;}while(p!=NULL);if(op->size>fl->size){fl->start=op->start;op->start=fl->start+fl->size;op->size=op->size-fl->size;fl->next=op;fl->prior=op->prior;op->prior->next=fl;op->prior=fl;goto flag1;}if(op->size==fl->size){op->flag=fl->flag;op->name=fl->name;free(fl);goto flag1;}cout<<"内存过小,分配失败!"<<endl;goto flag2;flag1: cout<<"分配成功!"<<endl;flag2: ;}void dec(ptr &p){//最坏适应法的内存分配函数int max;ptr op;FreeLink *fl=(FreeLink *)malloc(sizeof(FreeLink));cout<<"请输入要分配内存的进程名"<<endl;cin>>fl->name;cout<<"请输入要分配内存的大小"<<endl;cin>>fl->size;max=fl->size;fl->flag=true;do{if(p->flag==false&&p->size>=max){max=p->size;op=p;}p=p->next;}while(p!=NULL);if(op->size>fl->size){fl->start=op->start;op->start=fl->start+fl->size;op->size=op->size-fl->size;fl->next=op;fl->prior=op->prior;op->prior->next=fl;op->prior=fl;goto flag3;}if(op->size==fl->size){op->flag=fl->flag;op->name=fl->name;free(fl);goto flag3;}cout<<"内存过小,分配失败!"<<endl;goto flag4;flag3: cout<<"分配成功!"<<endl;flag4: ;}void splice(ptr &p){//若被操作的内存有相邻空闲区则将空闲区拼接合并int x;if(p->prior->flag==false&&p->next->flag==false)x=1;if((p->prior->flag==false&&p->next->flag==true)||(p->prior->flag==false&& p->next==NULL))x=2;if((p->prior->flag==true&&p->next->flag==false)||(p->prior==NULL&&p->next ->flag==false))x=3;if((p->prior->flag==true&&p->next->flag==true)||(p->prior==NULL&&p->next->flag==true)||(p->prior->flag==true&&p->next==NULL))x=4;switch(x){case 1:p->next->prior=p->prior;p->prior->next=p->next;p->prior->size=p->prior->size+p->size+p->next->size;p->prior->next=p->next->next;if(p->next->next!=NULL)p->next->next->prior=p->next->prior;free(p->next);free(p);break;case 2:if(p->next==NULL){p->prior->next=p->next;}else{p->next->prior=p->prior;p->prior->next=p->next;}p->prior->size=p->prior->size+p->size;free(p);break;case 3:if(p->prior==NULL){top=p->next;p->next->prior=NULL;p->next->start=p->start;p->next->size=p->next->size+p->size;}else{p->next->prior=p->prior;p->prior->next=p->next;p->next->start=p->start;p->next->size=p->next->size+p->size;}free(p);break;case 4:p->name='@';p->flag=false;break;}}void allocate(ptr &p){//最先适应法的内存分配函数FreeLink *fl=(FreeLink *)malloc(sizeof(FreeLink));cout<<"请输入要分配内存的进程名"<<endl;cin>>fl->name;cout<<"请输入要分配内存的大小"<<endl;cin>>fl->size;fl->flag=true;do{if(p->flag==false&&p->size>fl->size){fl->start=p->start;p->start=fl->start+fl->size;p->size=p->size-fl->size;fl->next=p;fl->prior=p->prior;p->prior->next=fl;p->prior=fl;goto a;}if(p->flag==false&&p->size==fl->size){p->flag=fl->flag;p->name=fl->name;free(fl);goto a;}p=p->next;}while(p!=NULL);cout<<"内存过小,分配失败!"<<endl;goto b;a: cout<<"分配成功!"<<endl;b: ;}void recover(ptr &p){//内存回收函数char n = ' ';cout<<"请输入要回收的内存对应的进程名";cin>>n;do{if(p->flag==true&&p->name==n){splice(p);goto c;}p=p->next;}while(p!=NULL);cout<<"内存并未分配给对应进程,回收失败!"<<endl;goto d; c: cout<<"内存回收成功!"<<endl;d: ;}int ffa(){//最先适应法char choice=' ';print();ptr pcb=(FreeLink *)malloc(sizeof(FreeLink));pcb->next=top;pcb->prior=top->prior;top->prior=pcb;pcb->start=top->start;cout<<"请输入要为系统分配的内存块名"<<endl;cin>>pcb->name;cout<<"请输入要分配内存的大小"<<endl; goto f;e: cout<<"超过内存最大容量请重新输入要分配内存的大小"<<endl; f: cin>>pcb->size;if(pcb->size>256) goto e;top->size=top->size-pcb->size;top=pcb;top->flag=true;top->next->start+=top->size;print();while(true){do{p=top->next;cout<<"请从下列选项中进行选择"<<endl;cout<<"1.分配内存"<<endl;cout<<"2.回收内存"<<endl;cout<<"3.结束操作"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3');switch(choice){case '1':allocate(p);print();break;case '2':recover(p);print();break;case '3':clear();return 0;break;}}}int bfa(){//最佳适应法char choice=' ';print();ptr pcb=(FreeLink *)malloc(sizeof(FreeLink));pcb->next=top;pcb->prior=top->prior;top->prior=pcb;pcb->start=top->start;cout<<"请输入要为系统分配的内存块名"<<endl;cin>>pcb->name;cout<<"请输入要分配内存的大小"<<endl; goto h;g: cout<<"超过内存最大容量请重新输入要分配内存的大小"<<endl; h: cin>>pcb->size;if(pcb->size>256) goto g;top->size=top->size-pcb->size;top=pcb;top->flag=true;top->next->start+=top->size;print();while(true){do{p=top->next;cout<<"请从下列选项中进行选择"<<endl;cout<<"1.分配内存"<<endl;cout<<"2.回收内存"<<endl;cout<<"3.结束操作"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3');switch(choice){case '1':asc(p);print();break;case '2':recover(p);print();break;case '3':clear();return 0;break;}}}int wfa(){//最坏适应法char choice=' ';print();ptr pcb=(FreeLink *)malloc(sizeof(FreeLink));pcb->next=top;pcb->prior=top->prior;top->prior=pcb;pcb->start=top->start;cout<<"请输入要为系统分配的内存块名"<<endl;cin>>pcb->name;cout<<"请输入要分配内存的大小"<<endl; goto j;i: cout<<"超过内存最大容量请重新输入要分配内存的大小"<<endl; j: cin>>pcb->size;if(pcb->size>256) goto i;top->size=top->size-pcb->size;top=pcb;top->flag=true;top->next->start+=top->size;print();while(true){do{p=top->next;cout<<"请从下列选项中进行选择"<<endl;cout<<"1.分配内存"<<endl;cout<<"2.回收内存"<<endl;cout<<"3.结束操作"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3');switch(choice){case '1':dec(p);print();break;case '2':recover(p);print();break;case '3':clear();return 0;break;}}}int main(){//主函数char choice = ' ';ptr free=(FreeLink *)malloc(sizeof(FreeLink));top=free;top->name='@';top->start=0;top->size=256;top->flag=false;top->prior=NULL;top->next=NULL;cout<<"***************Memory allocation and recovery algorithm***************"<<endl;cout<<"************************存储器的分配与回收算法************************"<<endl;while(true){do{cout<<"请从下列选项中进行选择"<<endl;cout<<"1.最先适应算法"<<endl;cout<<"2.最优适应算法"<<endl;cout<<"3.最坏适应算法"<<endl;cout<<"4.退出"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3'&&choice!='4');switch(choice){case '1':ffa();break;case '2':bfa();break;case '3':wfa();break;case '4':return 0;break;}}}四、实验结果最先适应法最佳适应法最坏适应法五.实验总结知道了存储器的分配与回收算法实现方法,采用最先适应法、最佳适应法、最坏适应法分配主存空间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告学院(系)名称:计算机与通信工程学院【实验过程记录(源程序、测试用例、测试结果及心得体会等)】源程序: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.链表应根据具体情况优化从而简化代码。