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

合集下载

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

实验报告二主存空间的分配和回收
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;

存储器管理实验实验报告

存储器管理实验实验报告

存储器管理实验实验报告一、实验目的存储器管理是操作系统的重要组成部分,本次实验的目的在于深入理解存储器管理的基本原理和方法,通过实际操作和观察,掌握存储器分配与回收的算法,以及页面置换算法的实现和性能评估。

二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。

三、实验内容与步骤(一)存储器分配与回收算法实现1、首次适应算法(1)原理:从空闲分区链的首地址开始查找,找到第一个满足需求的空闲分区进行分配。

(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态(已分配或空闲)。

当有分配请求时,从链表头部开始遍历,找到第一个大小满足需求的空闲分区。

将该分区进行分割,一部分分配给请求,剩余部分仍作为空闲分区留在链表中。

若找不到满足需求的空闲分区,则返回分配失败。

2、最佳适应算法(1)原理:从空闲分区链中选择与需求大小最接近的空闲分区进行分配。

(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。

当有分配请求时,遍历整个链表,计算每个空闲分区与需求大小的差值。

选择差值最小的空闲分区进行分配,若有多个差值相同且最小的分区,选择其中起始地址最小的分区。

对选中的分区进行分割和处理,与首次适应算法类似。

3、最坏适应算法(1)原理:选择空闲分区链中最大的空闲分区进行分配。

(2)实现步骤:建立空闲分区链表,每个节点包含分区的起始地址、大小和状态。

当有分配请求时,遍历链表,找到最大的空闲分区。

对该分区进行分配和处理。

(二)页面置换算法实现1、先进先出(FIFO)页面置换算法(1)原理:选择在内存中驻留时间最久的页面进行置换。

(2)实现步骤:建立页面访问序列。

为每个页面设置一个进入内存的时间戳。

当发生缺页中断时,选择时间戳最早的页面进行置换。

2、最近最久未使用(LRU)页面置换算法(1)原理:选择最近一段时间内最长时间未被访问的页面进行置换。

实现内存分配实验报告(3篇)

实现内存分配实验报告(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=(struct idle*)malloc(LEN2);
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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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.链表应根据具体情况优化从而简化代码。

相关文档
最新文档