内存分配算法实验报告

合集下载

实现内存分配实验报告(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. 创建一个动态内存分配模拟程序,包括空闲分区链表、分配函数和回收函数。

操作系统课程设计实验报告内存的持续分派算法

操作系统课程设计实验报告内存的持续分派算法

组号成绩运算机操作系统课程设计报告题目内存的持续分派算法专业:运算机科学与技术班级:学号姓名:指导教师:2016年12月26 日一、设计目的把握内存的里联系分派方式的各类算法。

二、设计内容本系统模拟操作系统内存分派算法的实现,实现可重定位分区分派算法,采纳PCB概念结构体来表示一个进程,概念了进程的名称和大小,进程内存起始地址和进程状态。

内存分区表用空闲分区表的形式来模拟实现。

三、设计原理动态分区的实现是依照进程所申请的内存大小来决定动态的由系统进行分派内存空间大小,因此分区内外的空闲分区个数是不定的,依照进程数和进程大小决定的。

可重定位分区算法比动态分区算法增加了紧凑的功能。

四、详细设计及编码1、模块分析该实验可分为三大部份,每一部份又由个数不同的几个函数实现。

第一部份是装入作业,第二部份是内存回收,第三部份是进行紧凑。

装入作业的时候第一初始化一个链表,依照用户输入的操作代号进行相应的操作。

假设用户选择装入作业第一判定空闲分区内外有无比作业需要的内存大的分区,假设有直接分派,假设没有进行紧凑操作,再将紧凑后的空闲分区与作业大小比较,假设能装的下那么分派给作业,假设是进行紧凑后的空闲分区仍不能装入整个作业那么通知用户内存不够。

2、流程图2、 代码实现 检索空闲分区链进行紧凑形成连空闲分区总N Y N找到>的分无法分请求分配修改有关的数据进行紧凑形成连按动态分区方式Y 返回分区号及首址#include<>#include<>#include<>#include<>#define TURE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define SIZE 3StartAddr>pList[j+1].pStartAddr){temp=pList[j];pList[j]=pList[j+1];pList[j+1]=temp;}}}}void compact(LinkList &L,struct PCB *pList){StartAddr=0; StartAddr=pList[i].pStartAddr+pList[i].pOccupy;}StartAddr+pList[pLength-1].pOccupy;s->areaSize=sumEmpty;ListInsert(L,s);No;delPSize=pList[index-1].pSize;delPOccupy=pList[index-1].pOccupy;delPStartAddr=pList[index-1].pStartAddr;StartAddr,pList[i].pOccupy,pList[i].pNo);}}void distribute(LinkList &L,struct PCB *process){LinkList p=L->next;while(p!=NULL){if(p->areaSize>=process->pSize)break;p=p->next;}//printf("%d KB < %dKB",process->pSize,p->areaSize);////////////////////if(p->areaSize-process->pSize<=SIZE){//不用分割全数分派(直接删除此空闲分区结点)process->pStartAddr=p->aStartAddr; //进程始址转变process->pState=1; //进程状态process->pOccupy=p->areaSize; //进程实际占用内存为改空闲分区的大小pList[pLength++]= *process; //把进程加入进程列表pSort(pList);pListPrint(pList);//输出内存中空间占用情形DeleteElem(L,p->aStartAddr);}else{//分割分派process->pStartAddr=p->aStartAddr; //进程始址转变process->pState=1; //进程状态process->pOccupy=process->pSize; //进程实际占用内存为该进程的大小pList[pLength++]= *process; //把进程加入进程列表pSort(pList); //进程排序pListPrint(pList);//输出内存中空间占用情形p->aStartAddr+=process->pSize; //空闲分区始址转变p->areaSize-=process->pOccupy; //空闲分区大小转变}}///////////////////////////////////////////////////////int main(){struct PCB p;int i,num,dele,k,stAddr,flag;LinkList s,L;if(!InitList(L)) //初始化空闲分区表printf("创建表失败\n");while(1){printf("请选择要进行的操作(1:装入;2:回收)");int flag;scanf("%d",&flag);if(flag==1){creatP(&p);//初始化进程//printf("______________________________________________________________________ __________");printf("待装入作业:%d Size = %d KB\n",,;//1、请求分派size//2、检索空闲分区表(第一次适应FF)//PrintList(L);stAddr=search(L,;//取得足够大的分区的始址,没有那么返回-1 if(stAddr==-1){//没有足够大的分区if(add(L)>={//空闲区总和足够大// printf("没有足够大的空闲分区但空闲总和足够大\n");//紧凑compact(L,pList);//按动态分区方式分派distribute(L,&p);PrintList(L);//compact(L,pList); //紧凑}else{ //空闲区总和不足printf("分派失败\n\n");}}else{//有足够大的distribute(L,&p);PrintList(L);//compact(L,pList); //紧凑}}else{//回收if(pLength>0){recycle(L,pList);//compact(L,pList); //紧凑}else{printf("无可回收内存!");}}//system("pause");// scanf("%d")} //whilereturn 0;}四、结果及其相关分析结果分析:持续进行4次装入的操作后内存中还剩30K的空间,接着进行一次回收内存的操作,回收作业1后不持续的空闲内存共有50K,接着再装入一个35K的作业,分散的两个分区都不能装入作业,可是总和能够装入,因此先进行紧凑再分派,从头分派后还剩15K 的内存。

动态内存分配实验报告

动态内存分配实验报告

Free[free_p].len=length;
free_p++;
//
sort(Free,Free+free_p,cmp);
for(j=0;j<free_p;j++)
{
1].address)
if(j + 1 < free_p&&Free[j].address+Free[j].len==Free[j +
if(used[i].run_id==id) {
int add=used[i].address; int length=used[i].len; used_p--; for(j=i;j<used_p;j++) {
used[j]=used[j+1]; }
Free[free_p].address=add;
Free[i].address+=len; Free[i].len-=len; } else { free_p--;
for(j=i;j<free_p;j++) {
Free[j]=Free[j+1]; } } break; } }
} void reclaim(int id) {
int i,j,k; for(i=0;i<used_p;i++) {
{ Free[j].len+=Free[j + 1].len; free_p--; for(k =j + 1; k < free_p;k++) { Free[k]=Free[k+1]; }
}
}
} }
} void show() {

操作系统-动态分区分配算法实验报告

操作系统-动态分区分配算法实验报告

实验题目:存储器内存分配设计思路:1.既然是要对内存进行操作,首先对和内存相关的内容进行设置我使用的是用自定义的数据结构struct来存放内存中一个内存块的内容包括:始地址、大小、状态(f:空闲u:使用e:结束)之后采用数组来存放自定义的数据类型,这样前期的准备工作就完成了2.有了要加工的数据,接下来定义并实现了存放自定义数据类型的数组的初始化函数和显示函数,需要显示的是每个内存块的块号、始地址、大小、状态3.接着依此定义三种动态分区分配算法首次适应算法、最佳适应算法和最差适应算法4.对定义的三种算法逐一进行实现①首次适应算法:通过遍历存放自定义数据类型的数组,找到遍历过程中第一个满足分配大小的内存块块号i,找到之后停止对数组的遍历,将i之后的块号逐个向后移动一个,然后将满足分配大小的内存块i分为两块,分别是第i块和第i+1块,将两块的始地址、大小、状态分别更新,这样便实现了首次适应算法②最佳适应算法:和首次适应算法一样,首先遍历存放自定义数据类型的数组,找到满足分配大小的内存块后,对内存块的大小进行缓存,因为最佳适应是要找到最接近要分配内存块大小的块,所以需要遍历整个数组,进而找到满足分配大小要求的而且碎片最小的块i,之后的操作和首次遍历算法相同③最差适应算法:和最佳适应算法一样,区别在于,最佳适应是找到最接近要分配内存块大小的块,而最差适应是要找到在数组中,内存最大的块i,找到之后的操作和最佳适应算法相同,因此不在这里赘述。

5.定义并实现释放内存的函数通过块号找到要释放的内存块,把要释放的内存块状态设置成为空闲,查看要释放的块的左右两侧块的状态是否为空闲,如果有空闲,则将空闲的块和要释放的块进行合并(通过改变块的始地址、大小、状态的方式)6.定义主函数,用switch来区分用户需要的操作,分别是:①首次适应②最佳适应③最差适应④释放内存⑤显示内存⑥退出系统实验源程序加注释:#include<bits/stdc++.h>#define MI_SIZE 100 //内存大小100typedef struct MemoryInfomation//一个内存块{int start; //始地址int Size; //大小char status; //状态 f:空闲 u:使用 e:结束} MI;MI MList[MI_SIZE];void InitMList() //初始化{int i;MI temp = { 0,0,'e' };for (i = 0; i < MI_SIZE; i++){MList[i] = temp;}MList[0].start = 0; //起始为0MList[0].Size = MI_SIZE;//大小起始最大MList[0].status = 'f'; //状态起始空闲}void Display() //显示{int i, used = 0;printf("\n---------------------------------------------------\n");printf("%5s%15s%15s%15s", "块号", "始地址", "大小", "状态");printf("\n---------------------------------------------------\n");for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].status == 'u'){used += MList[i].Size;}printf("%5d%15d%15d%15s\n", i, MList[i].start, MList[i].Size, MList[i].status == 'u' ? "使用" : "空闲");}printf("\n----------------------------------------------\n");}void FirstFit(){int i, j, flag = 0;int request;printf("最先适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f') {if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request; MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';flag = 1;}break;}}if (flag != 1 || i == MI_SIZE || MList[i].status == 'e'){printf("没有足够大小的空间分配\n");}Display();}void BadFit(){int i, j = 0, k = 0, flag = 0, request;printf("最坏适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0;i < MI_SIZE - 1 && MList[i].status != 'e';i++){if (MList[i].Size >= request && MList[i].status == 'f') {flag = 1;if (MList[i].Size > k){k = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2;j > i;j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}void M_Release() //释放内存{int i, number;printf("\n请问你要释放哪一块内存:\n");scanf("%d", &number);if (MList[number].status == 'u'){MList[number].status = 'f';if (MList[number + 1].status == 'f')//右边空则合并{MList[number].Size += MList[number].Size;for (i = number + 1; i < MI_SIZE - 1 && MList[i].status != 'e'; i++) { //i后面的每一个结点整体后移if (i > 0){MList[i] = MList[i + 1];}}}if (number > 0 && MList[number - 1].status == 'f')//左边空则合并{MList[number - 1].Size += MList[number].Size;for (i = number; i < MI_SIZE - 1 && MList[i].status != 'e'; i++){MList[i] = MList[i + 1];}}}else{printf("该块内存无法正常释放\n");}Display();}void BestFit(){int i, j = 0, t, flag = 0, request;printf("最佳适应算法:请问你要分配多大的内存\n");scanf("%d", &request);t = MI_SIZE;for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f'){flag = 1;if (MList[i].Size < t){t = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else {for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}int main(){int x;InitMList();while (1){printf(" \n"); printf(" 1.首次适应\n");printf(" 2.最佳适应\n");printf(" 3.最差适应\n"); printf(" 4.释放内存\n"); printf(" 5.显示内存\n"); printf(" 6.退出系统\n"); printf("请输入1-6:");scanf("%d", &x);switch (x){case 1:FirstFit();break;case 2:BestFit();break;case 3:BadFit();break;case 4:M_Release();break;case 5:Display();break;case 6:exit(0);}}return 0;}实验测试结果记录:1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存10---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 90 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 65 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存15---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 50 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存20---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:2---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 空闲3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:2最佳适应算法:请问你要分配多大的内存5---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:3最坏适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 25 使用6 95 5 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。

内存连续分配方式实验

内存连续分配方式实验

内存连续分配方式实验内存连续分配是操作系统中的重要概念之一、在计算机系统中,内存分配是指将进程所需的内存空间分配给其使用,同时也需要满足内存管理的要求。

内存连续分配方式是指将进程所需的内存空间连续地划分并分配给进程。

下面将介绍内存连续分配的几种方式及实验。

1.固定分区分配方式:固定分区分配方式是将整个内存空间分为若干个大小相等的分区,并为每个分区分配一个进程。

这种分配方式适用于进程数固定或进程大小相对稳定的场景。

固定分区分配方式的优点是简单易实现,缺点是可能会造成内存空间浪费,同时,当进程数或进程大小发生变化时,需要重新划分分区,性能较差。

2.动态分区分配方式:动态分区分配方式是根据进程的实际需要动态地分配内存空间。

动态分区分配方式将内存空间划分为若干个大小不等的分区,每个分区都可以独立地分配给进程使用。

当有新进程需要内存空间时,系统会根据分区空闲情况找到合适的分区进行分配。

动态分区分配方式的优点是充分利用内存空间,缺点是可能会出现内存碎片问题。

3.伙伴系统分配方式:伙伴系统分配方式是一种动态分区分配方式的改进版本。

它将内存空间划分为若干个大小相等的块,每个块大小都是2的幂。

当有新进程需要内存空间时,系统会找到与其大小最接近的空闲块进行分配。

如果找到的块大于所需大小,则将其划分为两个大小相等的块,其中一个分配给进程,另一个留作备用;如果找到的块小于所需大小,则会继续查找更大的空闲块进行分配。

伙伴系统分配方式的优点是减少了内存碎片问题,缺点是实现较为复杂。

实验设计:1.实验目的:通过实验,测试和比较不同的内存连续分配方式在不同场景下的性能和效果。

2.实验环境:使用一台具备内存管理功能的计算机,并在上面运行操作系统。

3.实验步骤:a.首先,选择一种内存连续分配方式,如固定分区分配方式。

b.根据选择的分配方式,设置相应的分区大小和数量。

c.运行一些需要内存空间的进程,并观察它们的分配情况。

d.记录每个进程所分配到的内存空间大小和位置,以及未分配的内存空间大小和位置。

操作系统实验内存分配

操作系统实验内存分配

西安邮电大学(计算机学院)课内实验报告实验名称:内存管理专业名称:软件工程班级:学生姓名:学号(8位):指导教师:实验日期:实验五:进程1.实验目的通过深入理解区管理的三种算法,定义相应的数据结构,编写具体代码。

充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣。

(1)掌握内存分配FF,BF,WF策略及实现的思路;(2)掌握内存回收过程及实现思路;(3)参考给出的代码思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。

2.实验要求:1)掌握内存分配FF,BF,WF策略及实现的思路;2)掌握内存回收过程及实现思路;3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。

3.实验过程:创建进程:删除其中几个进程:(默认以ff首次适应算法方式排列)Bf最佳适应算法排列方式:wf最差匹配算法排列方式:4.实验心得:这次实验实验时间比较长,而且实验指导书中对内存的管理讲的很详细,老师上课的时候也有讲的很详细,但是代码比较长,刚开始的时候也是不太懂,但是后面经过和同学一起商讨,明白几种算法的含义:①首次适应算法。

在采用空闲分区链作为数据结构时,该算法要求空闲分区链表以地址递增的次序链接。

在进行内存分配时,从链首开始顺序查找,直至找到一个能满足进程大小要求的空闲分区为止。

然后,再按照进程请求内存的大小,从该分区中划出一块内存空间分配给请求进程,余下的空闲分区仍留在空闲链中。

②循环首次适应算法。

该算法是由首次适应算法演变而形成的,在为进程分配内存空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,并从中划出一块与请求的大小相等的内存空间分配给进程。

③最佳适应算法将空闲分区链表按分区大小由小到大排序,在链表中查找第一个满足要求的分区。

④最差匹配算法将空闲分区链表按分区大小由大到小排序,在链表中找到第一个满足要求的空闲分区。

实验4 可变分区的内存分配算法

实验4 可变分区的内存分配算法

实验4可变分区的内存分配算法模拟1.实验目的通过模拟可变分区的以下内存分配算法,掌握连续分配存储器管理的特点,掌握以下四种分配算法的优缺点并进行对比。

(1)首次适应分配算法;(2)循环适应分配算法;(3)最佳适应分配算法;(4)最坏适应分配算法。

2.实验环境装有操作系统WindowsXP和开发工具VC++6.0,内存在256M以上的微机;或者:装有Linux(Fedora7)操作系统和gcc编译器,内存在256M以上的微机。

3.实验内容(1)用户可用的内存空间为64K,按下面的现有分区情况进行初始化,可在屏幕上显示(2)接收用户进程的内存申请格式为:作业名、申请空间的大小。

按照上述的一种分配算法进行分配,修改空闲分区表,并在屏幕上显示分配后的内存状态。

(3)用户进程执行完成后,或者从外部撤销用户进程,将内存进行回收,修改空闲分区表,并在屏幕上显示回收后的内存状态。

4.实验要求(1)将四种算法的源程序及程序执行结果写入实验报告;(2)将四种算法的工作机理写入实验报告。

代码:#include<iostream.h>#include<stdlib.h>#defineFree0//空闲状态#defineBusy1//已用状态#defineOK1//完成#defineERROR0//出错#defineMAX_length64〃最大内存空间为64KBtypedefintStatus;intflag;typedefstructfreearea//定义一个空闲区说明表结构{longsize;//分区大小longaddress;//分区地址intstate;//状态}ElemType;//线性表的双向链表存储结构typedefstructDuLNode{ElemTypedata;structDuLNode*prior;//前趋指针structDuLNode*next;//后继指针}DuLNode,*DuLinkList;DuLinkListblock_first;//头结点DuLinkListblock_last;//尾结点Statusalloc(int);//内存分配Statusfree(int);//内存回收Status尸1凤_行均位);//首次适应算法StatusBest_fit(int);//最佳适应算法StatusWorst_fit(int);//最差适应算法voidshow();//查看分配StatusInitblock();//开创空间表StatusInitblock()//开创带头结点的内存空间链表{block_first=(DuLinkList)malloc(sizeof(DuLNode));block_last=(DuLinkList)malloc(sizeof(DuLNode));block_first->prior=NULL;block_first->next=block_last;block_last->prior=block_first;block_last->next=NULL;block_last->data.address=0;block_last->data.size=MAX_length;block_last->data.state=Free;returnOK;}//分配主存Statusalloc(intch){intrequest=0;cout<<”请输入需要分配的主存大小(单位:KB):”;cin>>request;if(request<0||request==0){cout<<"分配大小不合适,请重试!"<<endl;returnERROR;}if(ch==2)//选择最佳适应算法{if(Best_fit(request)==OK)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;returnOK;}if(ch==3)//选择最差适应算法{if(Worst_fit(request)==OK)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;returnOK;}else//默认首次适应算法{if(First_fit(request)==OK)cout<<"分配成功!"<<endl;elsecout<<"内存不足,分配失败!"<<endl;returnOK;}}//首次适应算法StatusFirst_fit(intrequest){//为申请作业开辟新空间且初始化DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode*p=block_first->next;while(p){if(p->data.state==Free&&p->data.size==request){//有大小恰好合适的空闲块p->data.state=Busy;returnOK;break;}if(p->data.state==Free&&p->data.size>request){//有空闲块能满足需求且有剩余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-=request;returnOK;break;}p=p->next;}returnERROR;}//最佳适应算法StatusBest_fit(intrequest){intch;//记录最小剩余空间DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode*p=block_first->next;DuLNode*q=NULL;//记录最佳插入位置while(p)//初始化最小空间和最佳位置{if(p->data.state==Free&&(p->data.size>=request)){if(q==NULL){q=p;ch=p->data.size-request;}elseif(q->data.size>p->data.size){q=p;ch=p->data.size-request;}}p=p->next;}if(q==NULL)returnERROR;//没有找到空闲块elseif(q->data.size==request) {q->data.state=Busy;returnOK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.size=ch;returnOK;}returnOK;}//最差适应算法StatusWorst_fit(intrequest){intch;//记录最大剩余空间DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode*p=block_first->next;DuLNode*q=NULL;//记录最佳插入位置while(p)//初始化最大空间和最佳位置{if(p->data.state==Free&&(p->data.size>=request)){if(q==NULL){q=p;ch=p->data.size-request;}elseif(q->data.size<p->data.size){q=p;ch=p->data.size-request;}}p=p->next;}if(q==NULL)returnERROR;//没有找到空闲块elseif(q->data.size==request){q->data.state=Busy;returnOK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.size=ch;returnOK;}returnOK;}//主存回收Statusfree(intflag){DuLNode*p=block_first;for(inti=0;i<=flag;i++)if(p!=NULL)p=p->next;elsereturnERROR;p->data.state=Free;if(p->prior!=block_first&&p->prior->data.state==Free)〃与前面的空闲块相连( p->prior->data.size+=p->data.size;p->prior->next=p->next;p->next->prior=p->prior;p=p->prior;}if(p->next!=block_last&&p->next->data.state==Free)//与后面的空闲块相连(p->data.size+=p->next->data.size;p->next->next->prior=p;p->next=p->next->next;}if(p->next==block_last&&p->next->data.state==Free)//与最后的空闲块相连(p->data.size+=p->next->data.size;p->next=NULL;}returnOK;}//显示主存分配情况voidshow()(intflag=0;cout<<"\n主存分配情况:\n";cout<<"++++++++++++++++++++++++++++++++++++++++++++++\n\n";DuLNode*p=block_first->next;cout<<"分区号\t起始地址\t分区大小\t状态\n\n”;while(p)(cout<<""<<flag++<<"\t";cout<<""<<p->data.address<<"\t\t";cout<<""<<p->data.size<<"KB\t\t";if(p->data.state==Free)cout<<"空闲\n\n";elsecout<<"已分配\n\n";p=p->next;cout«"++++++++++++++++++++++++++++++++++++++++++++++\n\rT;〃主函数voidmain()(intch;〃算法选择标记coukv”请输入所使用的内存分配算法:\n";cout<<”⑴首次适应算法\n⑵最佳适应算法\n⑶最差适应算法\n”;cin»ch;while(ch<l||ch>3)(cout<<“输入错误,请重新输入所使用的内存分配算法:\n";cin»ch;}lnitblock();〃开仓1J空间表intchoice;〃操作选择标记while(l)(show();coukv"请输入您的操作:";cout«"\nl:分配内存\n2:回收内存\n0:退出\rT;cin»choice;if(choice==l)alloc(ch);//分配内存elseif(choice==2)//内存回收(intflag;cout<<”请输入您要释放的分区号:”;cin»flag;free(flag);}elseif(choice==0)break;〃退出else〃输入操作有误(coutvv'1输入有误,请重试!"vvendl;continue;结果:首次适应算法(FirstFit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。

操作系统实验之内存管理实验报告

操作系统实验之内存管理实验报告

操作系统实验之内存管理实验报告一、实验目的内存管理是操作系统的核心功能之一,本次实验的主要目的是深入理解操作系统中内存管理的基本原理和机制,通过实际编程和模拟操作,掌握内存分配、回收、地址转换等关键技术,提高对操作系统内存管理的认识和实践能力。

二、实验环境本次实验在 Windows 操作系统下进行,使用 Visual Studio 作为编程环境,编程语言为 C++。

三、实验原理1、内存分配算法常见的内存分配算法有首次适应算法、最佳适应算法和最坏适应算法等。

首次适应算法从内存的起始位置开始查找,找到第一个满足需求的空闲分区进行分配;最佳适应算法则选择大小最接近需求的空闲分区;最坏适应算法选择最大的空闲分区进行分配。

2、内存回收算法当进程结束释放内存时,需要将其占用的内存区域回收至空闲分区链表。

回收过程中需要考虑相邻空闲分区的合并,以减少内存碎片。

3、地址转换在虚拟内存环境下,需要通过页表将逻辑地址转换为物理地址,以实现进程对内存的正确访问。

四、实验内容1、实现简单的内存分配和回收功能设计一个内存管理模块,能够根据指定的分配算法为进程分配内存,并在进程结束时回收内存。

通过模拟多个进程的内存请求和释放,观察内存的使用情况和变化。

2、实现地址转换功能构建一个简单的页式存储管理模型,模拟页表的建立和地址转换过程。

给定逻辑地址,能够正确计算出对应的物理地址。

五、实验步骤1、内存分配和回收功能实现定义内存分区的数据结构,包括起始地址、大小、使用状态等信息。

实现首次适应算法、最佳适应算法和最坏适应算法的函数。

创建空闲分区链表,初始化为整个内存空间。

模拟进程的内存请求,调用相应的分配算法进行内存分配,并更新空闲分区链表。

模拟进程结束,回收内存,处理相邻空闲分区的合并。

2、地址转换功能实现定义页表的数据结构,包括页号、页框号等信息。

给定页面大小和逻辑地址,计算页号和页内偏移。

通过页表查找页框号,结合页内偏移计算出物理地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

成绩评定表课程设计任务书目录一、题目概述(内容及要求) (4)二、功能分析............................ 错误!未定义书签。

三、设计 (6)四、运行与测试 (7)五、总结 (17)参考文献 (18)1.设计目的1)了解多道程序系统中,多个进程并发执行的内存资源分配;2)模拟可变分区内存储管理算法实现分区管理的最佳适应分配算法;3)通过实现最佳算法来进一步了解静态分区模式的优缺点;4)掌握最佳适应分配算法,深刻了解各进程在内存中的具体分配策略。

2.总体设计3.关键技术allocate():实现内存分配,并当中调用display(pbc),以及display(S)两个函数显示内存分配完成后的空闲块链表和进程链表情况。

requireback():实现内存回收,在满足情况的条件下调动allocate()对用户社情的内存块进行回收并在当中调用display(pbc),以及display(S)两个函数显示内存分配完成后的空闲块链表和进程链表情况。

callback():按内存回收时的四种情况对内存进行回收。

display(pbc):对空闲块链表中的空闲快惊醒从小到大排序并显示空闲链情况。

display(S): 对进程链表中的进程进行从小到大排序并显示进程链情况。

main():创建并初始化空闲块链表和进程链链表,用户选择操作功能。

4.程序流程图4-1图4-2 5.主要源代码#include<stdio.h>#include<iostream.h>#include<string.h>#include<iomanip.h>const int MAXJOB=100; //定义表最大记录数typedef struct node{int start; //空闲分区的起始地址int length; //空闲分区的长度char tag[20]; //分区信息是否已分配}job;job frees[MAXJOB]; //定义空闲区表int free_quantity; //空闲区的个数job occupys[MAXJOB];//定义已分配区表int occupy_quantity; //已分配区的个数//初始化函数void initial() {int i;for(i=0;i<MAXJOB;i++){frees[i].start=-1;frees[i].length=0;strcpy(frees[i].tag,"free");occupys[i].start=-1;occupys[i].length=0;strcpy(occupys[i].tag,""); }free_quantity=0;occupy_quantity=0;}//读数据函数int readData() {FILE *fp;char fname[20];cout<<endl<<" 》》欢迎进入主存储器空间的分配与回收模拟系统《《 "<<endl; cout<<endl<<endl<<"请输入初始空闲表文件名:";cin>>fname;if((fp=fopen(fname,"r"))==NULL) //读文件cout<<endl<<" 错误,文件打不开,请检查文件名!"<<endl;else{while(!feof(fp)) //文件结束{fscanf(fp,"%d",&frees[free_quantity].start);fscanf(fp,"%d",&frees[free_quantity].length);free_quantity++; }return 1; }return 0;}//sort选择——排序void sort() {int i,j,p;for(i=0;i<free_quantity-1;i++){p=i;for(j=i+1;j<free_quantity;j++)//空闲分区按地址递增的顺序排列 { if(frees[j].start<frees[p].start){ p=j; }}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity]; }}}//显示函数void view() {int i;cout<<endl<<"-------------------------------------------"<<endl; cout<<"当前空闲表:"<<endl;cout<<"起始地址长度状态"<<endl;for(i=0;i<free_quantity;i++){cout.setf(2);cout.width(12);cout<<frees[i].start;cout.width(10);cout<<frees[i].length;cout.width(8);cout<<frees[i].tag<<endl;}cout<<endl<<"------------------------------------------"<<endl; cout<<"当前已分配表:"<<endl;cout<<"起始地址长度占用作业名"<<endl;for(i=0;i<occupy_quantity;i++) {cout.setf(2);cout.width(12);cout<<occupys[i].start;cout.width(10);cout<<occupys[i].length;cout.width(8);cout<<occupys[i].tag<<endl; }}//最先适应分配算法void earliest() {//空闲分区按地址递增的顺序排列char job_name[20];int job_length;int i,j,flag,t;cout<<endl<<" 请输入新申请内存空间的作业名和空间大小:"; cin>>job_name; //输入作业的名称cin>>job_length; //输入作业的长度flag=0; //分配成功与否信号for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length) {flag=1; //可以分配} }if(flag==0){cout<<endl<<" Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试……"<<endl; }else{t=0;i=0;while(t==0){if(frees[i].length>=job_length)//从空闲分区表顺序查找,直到找到第一能满足其大小要求的空闲分区为止{ t=1; }i++;}i--;occupys[occupy_quantity].start=frees[i].start; //修改已分区的相关信息strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length;}else //刚好分配则空闲分区数减一{ for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1]; }free_quantity--;cout<<endl<<" 内存空间成功!"<<endl; }}}//最优适应分配算法void excellent() {//空闲分区按大小递增的顺序排列char job_name[20];int job_length;int i,j,flag,t;cout<<endl<<" 请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length){flag=1;}}if(flag==0){cout<<endl<<" Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试!"<<endl; }else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){t=1;}i++;}i--;for(j=0;j<free_quantity;j++){if((frees[j].length>=job_length)&&(frees[j].length<frees[i].length)) { i=j; }}occupys[occupy_quantity].start=frees[i].start;strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length; }else{for(j=i;j<free_quantity-1;j++){ frees[j]=frees[j+1]; }free_quantity--;cout<<endl<<" 内存空间成功!"<<endl; }}}//最坏适应算法void worst() {//空闲分区按大小递减的顺序排列char job_name[20];int job_length;int i,j,flag,t;cout<<endl<<" 请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length)flag=1;}if(flag==0)cout<<endl<<" Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试!"<<endl;else{t=0;i=0;while(t==0){if(frees[i].length>=job_length)t=1;i++;}i--;for(j=0;j<free_quantity;j++){if((frees[j].length>=job_length)&&(frees[j].length>frees[i].length))i=j;}occupys[occupy_quantity].start=frees[i].start;strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<endl<<" 内存空间成功!"<<endl; }}}//撤消作业void finished() {char job_name[20];int i,j,flag,p=0;int start;int length;cout<<endl<<" 请输入要撤消的作业名:"; cin>>job_name;flag=-1;for(i=0;i<occupy_quantity;i++){if(!strcmp(occupys[i].tag,job_name)){flag=i;start=occupys[i].start;length=occupys[i].length; }}if(flag==-1){cout<<"没有这个作业名"<<endl; }else{//加入空闲表for(i=0;i<free_quantity;i++){if((frees[i].start+frees[i].length)==start)//上空{ if(((i+1)<free_quantity)&&(frees[i+1].start==start+length)) { //上空且下空,不为最后一个frees[i].length=frees[i].length+frees[i+1].length+length;for(j=i+1;j<free_quantity;j++)frees[j]=frees[j+1];free_quantity--;p=1;}else{frees[i].length+=length; //上空且下不空p=1; }}if(frees[i].start==(start+length)) { //下空frees[i].start=start;frees[i].length+=length;p=1; }}//空闲中没有if(p==0){frees[free_quantity].start=start;frees[free_quantity].length=length;free_quantity++;}//删除分配表中的该作业for(i=flag;i<occupy_quantity;i++)occupys[i]=occupys[i+1];occupy_quantity--; }}void main(){ int flag=0;int t=1;int chioce=0;initial();flag=readData();while(flag==1){sort();cout<<endl<<endl;cout<<" ==========================================="<<endl; cout<<" 主存储器空间的分配与回收模拟"<<endl;cout<<" ==========================================="<<endl; cout<<" 1.首次适应算法申请空间"<<endl;cout<<" 2.最佳适应算法申请空间"<<endl;cout<<" 3.最坏适应算法申请空间"<<endl;cout<<" 4.撤消作业"<<endl;cout<<" 5.显示空闲表和分配表 "<<endl;cout<<" 0.退出"<<endl;cout<<endl<<" ——> 请选择:";cin>>chioce;switch(chioce){case 1: earliest(); break;case 2: excellent() ;break;case 3: worst() ;break;case 4: finished(); break;case 5: view(); break;case 0: flag=0; break;default: cout<<"选择错误!"<<endl; } }}//文件 fname6.运行结果及结论图6-1经验总结:程序设计时,最好将不同的功能用不同的函数实现。

相关文档
最新文档