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

合集下载

实验四动态分区分配算法实验报告及程序

实验四动态分区分配算法实验报告及程序

实验报告四动态分区分配算法班级学号姓名一、实验目的动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。

在本实验中运用了四种分配算法,分别是1.首次适应算法,2.循环首次适应算法,3.最坏适应算法4.最佳适应算法。

二、实验环境普通的计算机一台,编译环境Microsoft Visual C++ 6.0三、算法思想1.数据结构(1)分区开始地址startaddress(2)分区大小size(3)分区状态state2.功能介绍(1)首次适应算法在首次适应算法中,是从已建立好的数组中顺序查找,直至找到第一个大小能满足要求的空闲分区为止,然后再按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空间令开辟一块新的地址,大小为原来的大小减去作业大小,若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

(2)循环首次适应算法该算法是由首次适应算法演变而成,在为进程分配内存空间时,不再是每次都从第一个空间开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业,为实现本算法,设置一个全局变量f,来控制循环查找,当f%N==0时,f=0;若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

(3)最坏适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最大的空闲分区分配给作业。

(4)最佳适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最小的空闲分区分配给作业。

四、源程序#include <stdio.h>#define L 10typedef struct LNode{int startaddress;int size;int state;}LNode;LNodeP[L]={{0,128,0},{200,256,0},{500,512,0},{1 500,1600,0},{5000,150,0}};int N=5; int f=0;void print(){ int i;printf("起始地址分区状态\n");for(i=0;i<N;i++)printf("%3d %8d %4d\n",P[i].startaddress, P[i].size,P[i].state);}void First(){ int i,l=0,m;printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break; }else{P[N].startaddress=P[i].startaddress+m;P[N].size=P[i].size-m;P[i].size=m;P[i].state=1;l=1; N++;break; } }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void CirFirst(){ int l=0,m,t=0;printf("\n输入请求分配分区的大小:");scanf("%d",&m);while(f<N){ if(P[f].size<m){ f=f+1;if(f%N==0){ f=0;t=1;}continue; }if(P[f].size==m && P[f].state!=1){ P[f].state=1;l=1; f++;break; }if(P[f].size>m && P[f].state!=1){ P[N].startaddress=P[f].startaddress+m;P[N].size=P[f].size-m;P[f].size=m;P[f].state=1;l=1; N++;f++; break; } }if(l==1){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Worst(){int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1; break; }elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]>a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Best(){ int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break;}elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]<a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void main(){ int k=0;printf("动态分区分配算法:");while(k!=5){printf("\n~~~~~~~~主菜单~~~~~~~~~");printf("\n1、首次适应算法\n2、循环首次适应算法");printf("\n3、最坏适应算法\n4、最佳适应算法");printf("\n5、退出\n");printf("请选择算法:");scanf("%d",&k);switch(k){ case 1:printf("\n初始状态为:\n");print();First();continue;case 2:printf("\n初始状态为:\n");print();CirFirst();continue;case 3:printf("\n初始状态为:\n"); print();Worst();continue;case 4:printf("\n初始状态为:\n");print();Best();continue;case 5:break;default:printf("选择错误,请重新选择。

动态分区分配算法描述

动态分区分配算法描述

动态分区分配算法描述一、引入动态分区分配算法:在动态分区分配方式中,当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配?二、首次适应算法(First Fit)算法思想:每次都从低地址开始查找,找到第一个能满足大小的空闲分区。

如何实现:空闲分区以地址递增的次序排列。

每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。

三、最佳适应算法(Best Fit)算法思想:由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。

因此为了保证当“大进程”到来时能有连续的大片空间,可以尽可能多地留下大片的空闲区,即优先使用更小的空闲区。

如何实现:空闲分区按容量递增次序链接。

每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。

缺点:每次都选最小的分区进行分配,会留下越来越多的、很小的、难以利用的内存块。

因此这种方法会产生很多的外部碎片。

四、最坏适应算法(Worst Fit)又称最大适应算法(Largest Fit)算法思想:为了解决最佳适应算法的问题——即留下太多难以利用的小碎片,可以在每次分配时优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,更方便使用。

如何实现:空闲分区按容量递减次序链接。

每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。

重新排序:空闲分区按容量递减次序链接缺点:每次都选最大的分区进行分配,虽然可以让分配后留下的空闲区更大,更可用,但是这种方式会导致较大的连续空闲区被迅速用完。

如果之后有“大进程”到达,就没有内存分区可用了。

五、邻近适应算法(Next Fit)算法思想:首次适应算法每次都从链头开始查找的。

这可能会导致低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。

如果每次都从上次查找结束的位置开始检索,就能解决上述问题。

实验报告-动态分区分配算法

实验报告-动态分区分配算法

南昌大学实验报告学生姓名:马江涛学号:8000612091 专业班级:计算机软件121班实验类型:□验证□综合□设计□创新实验日期:2014-05-08 实验成绩:【实验要求】1、编程实现首次适应算法和最佳适应算法的动态分区分配的分配过程和回收过程。

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

2、假设初始状态下,可用内存空间为640K,并依次有下列请求序列:1)作业1申请130KB。

2)作业2申请60KB。

3)作业3申请100KB。

4)作业2释放60KB。

5)作业4申请200KB。

6)作业3释放100KB。

7)作业1释放130KB。

8)作业5申请140KB。

9)作业6申请60KB。

10)作业7申请50KB。

11)作业6释放60KB。

请分别用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况【可参考后文的实验提示】。

3、上机时认真的进行测试,输入不同的资源分配请求,写出实验结果;4、具体要求:(1)对你的程序关键代码处进行注释。

(2)给出实验数据,对结果进行分析,说明对相关知识点的理解。

【实验目的】了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。

【实验思路】首次适应算法(First-fit):当要分配内存空间时,就查表,在各空闲区中查找满足大小要求的可用块。

只要找到第一个足以满足要球的空闲块就停止查找,并把它分配出去;如果该空闲空间与所需空间大小一样,则从空闲表中取消该项;如果还有剩余,则余下的部分仍留在空闲表中,但应修改分区大小和分区始址。

最佳适应算法(Best-fit):当要分配内存空间时,就查找空闲表中满足要求的空闲块,并使得剩余块是最小的。

然后把它分配出去,若大小恰好合适,则直按分配;若有剩余块,则仍保留该余下的空闲分区,并修改分区大小的起始地址。

内存回收:将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。

实验四动态分区分配算法

实验四动态分区分配算法

实验容:存储器管理实验一、实验目的采用首次适应算法〔FF〕,最正确适应算法〔BF〕,最坏适应算法〔WF〕三种不同的算法,实现对系统空闲区的动态分区分配。

二、实验题目给予顺序搜索的动态分区算法的程序。

三、实验要求读懂给出的核心代码,进展适当的修改,编译通过后,完成实验报告。

四、核心代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>//常量定义#define PROCESS_NAME_LEN 32#define MIN_SLICE 10#define DEFAULT_MEM_SIZE 1024#define DEFAULT_MEM_START 0#define MA_FF 1#define MA_BF 2#define MA_WF 3int mem_size=DEFAULT_MEM_SIZE;int ma_algorithm = MA_FF;static int pid = 0;int flag = 0;struct free_block_type{int size;int start_addr;struct free_block_type *next;};struct free_block_type *free_block;//描述已分配的存块struct allocated_block{int pid; int size;int start_addr;char process_name[PROCESS_NAME_LEN];struct allocated_block *next;};struct allocated_block *allocated_block_head = NULL;//函数声明struct free_block_type* init_free_block(int mem_size);void display_menu();int set_mem_size();void set_algorithm();void rearrange(int algorithm);int rearrange_FF();int rearrange_BF();int rearrange_WF();int new_process();int allocate_mem(struct allocated_block *ab);void kill_process();int free_mem(struct allocated_block *ab);int dispose(struct allocated_block *free_ab);int display_mem_usage();void do_exit();struct allocated_block *find_process(int pid);int main(){char choice; pid=0;free_block= init_free_block(mem_size); //初始化空闲区while(1) {display_menu(); //显示菜单fflush(stdin);choice=getchar(); //获取用户输入switch(choice){case '1': set_mem_size(); break; //设置存大小case '2': set_algorithm();flag=1; break;//设置算法case '3': new_process(); flag=1; break;//创立新进程case '4': kill_process(); flag=1; break;//删除进程case '5': display_mem_usage(); flag=1; break; //显示存使用case '0': do_exit(); exit(0); //释放链表并退出default: break;}}return 1;}struct free_block_type* init_free_block(int mem_size){struct free_block_type *fb;fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));if(fb==NULL){printf("No mem\n");return NULL;}fb->size = mem_size;fb->start_addr = DEFAULT_MEM_START;fb->next = NULL;return fb;}void display_menu(){printf("\n");printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);printf("2 - Select memory allocation algorithm\n");printf("3 - New process \n");printf("4 - T erminate a process \n");printf("5 - Display memory usage \n");printf("0 - Exit\n");}int set_mem_size(){int size;if(flag!=0){ //防止重复设置printf("Cannot set memory size again\n");return 0;}printf("T otal memory size =");scanf("%d", &size);if(size>0) {mem_size = size;free_block->size = mem_size;}flag=1;return 1;}void set_algorithm(){int algorithm;while(1) {printf("\t1 - First Fit\n");printf("\t2 - Best Fit \n");printf("\t3 - Worst Fit \n");scanf("%d", &algorithm);if(algorithm>=1 && algorithm <=3) {ma_algorithm = algorithm;break;}elseprintf("输入有误,请重新输入!\n");}//按指定算法重新排列空闲区链表rearrange(ma_algorithm);}void rearrange(int algorithm){switch(algorithm){case MA_FF: rearrange_FF(); break;case MA_BF: rearrange_BF(); break;case MA_WF: rearrange_WF(); break;}}//首次适应算法int rearrange_FF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小地址的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小地址int min_addr = free_block->start_addr;temp = free_block;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_addr = thead->next->start_addr;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最正确适应算法int rearrange_BF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小存int min_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最坏适应算法int rearrange_WF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最大存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最大存int max_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {max_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}int new_process(){struct allocated_block *ab;int size;int ret;ab = (struct allocated_block *)malloc(sizeof(struct allocated_block));if(!ab) exit(-5);ab->next = NULL;pid++;sprintf(ab->process_name, "PROCESS-d", pid);ab->pid = pid;while(1) {printf("Memory for %s:", ab->process_name);scanf("%d", &size);if(size>0) {ab->size=size;break;}else printf("输入大小有误,请重新输入\n");}ret = allocate_mem(ab);if((ret==1) &&(allocated_block_head == NULL)){allocated_block_head=ab;return 1;}else if (ret==1) {ab->next = allocated_block_head;allocated_block_head = ab;return 2; }else if(ret==-1){printf("Allocation fail\n");pid--;free(ab);return -1;}return 3;}int allocate_mem(struct allocated_block *ab){struct free_block_type *fbt, *pre,*head,*temp,*tt;struct allocated_block *tp;int request_size=ab->size;int sum=0;int max;head = (struct free_block_type *)malloc(sizeof(struct free_block_type));pre = head;fbt = free_block;pre->next = fbt;if(ma_algorithm==MA_WF) {if(NULL==fbt||fbt->size<request_size)return -1;}else {while(NULL!=fbt&&fbt->size<request_size) {pre = fbt;fbt = fbt->next;}}if(NULL==fbt||fbt->size<request_size) {if(NULL!=free_block->next) {sum = free_block->size;temp = free_block->next;while(NULL!=temp) {sum += temp->size;if(sum>=request_size)break;temp = temp->next;}if(NULL==temp)return -1;else {pre = free_block;max = free_block->start_addr;fbt = free_block;while(temp->next!=pre) {if(max<pre->start_addr) {max = pre->start_addr;fbt = pre;}pre = pre->next;}pre = free_block;while(temp->next!=pre) {tp = allocated_block_head;tt = free_block;if(pre!=fbt) {while(NULL!=tp) {if(tp->start_addr>pre->start_addr)tp->start_addr = tp->start_addr - pre->size;tp = tp->next;}while(NULL!=tt) {if(tt->start_addr>pre->start_addr)tt->start_addr = tt->start_addr - pre->size;tt = tt->next;}}pre = pre->next;}pre = free_block;while(pre!=temp->next) {if(pre!=fbt)free(pre);pre = pre->next;}free_block = fbt;free_block->size = sum;free_block->next = temp->next;if(free_block->size - request_size < MIN_SLICE) {ab->size = free_block->size;ab->start_addr = free_block->start_addr;pre = free_block;free_block = free_block->next;free(pre);}else {ab->start_addr = fbt->start_addr;free_block->start_addr = free_block->start_addr + request_size;free_block->size = free_block->size - request_size;}}}elsereturn -1;}else {//将存块全局部配if(fbt->size - request_size < MIN_SLICE) {ab->size = fbt->size;ab->start_addr = fbt->start_addr;if(pre->next==free_block) {free_block = fbt->next;}elsepre->next = fbt->next;free(fbt);}else {ab->start_addr = fbt->start_addr;fbt->start_addr = fbt->start_addr + request_size;fbt->size = fbt->size - request_size;}}free(head);rearrange(ma_algorithm);return 1;}void kill_process(){struct allocated_block *ab;int pid;printf("Kill Process, pid=");scanf("%d", &pid);ab = find_process(pid);if(ab!=NULL){free_mem(ab);dispose(ab);}else {printf("没有pid为%d的进程!\n",pid);}}struct allocated_block *find_process(int pid) {struct allocated_block *ab=NULL;ab = allocated_block_head;while(NULL!=ab&&ab->pid!=pid)ab = ab->next;return ab;}int free_mem(struct allocated_block *ab){int algorithm = ma_algorithm;struct free_block_type *fbt, *pre=NULL,*head;fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));pre=(struct free_block_type*) malloc(sizeof(struct free_block_type));if(!fbt) return -1;// 进展可能的合并,根本策略如下// 1. 将新释放的结点插入到空闲分区队列末尾// 2. 对空闲链表按照地址有序排列// 3. 检查并合并相邻的空闲分区// 4. 将空闲链表重新按照当前算法排序head = pre;fbt->start_addr = ab->start_addr;fbt->size = ab->size;fbt->next = free_block; //新释放的结点插入到空闲分区链表的表头free_block = fbt;rearrange_FF(); //对空闲链表按照地址有序排列pre->next = free_block; //求的pre为fbt的前一个结点pre->size = 0;while(pre->next->start_addr!=fbt->start_addr)pre = pre->next;//左右分区都存在if(0!=pre->size&&NULL!=fbt->next) {//左右分区都可合并if((pre->start_addr+pre->size)==fbt->start_addr && (fbt->start_addr+fbt->size)==fbt->next->start_addr) {pre->size = pre->size + fbt->size + fbt->next->size;pre->next = fbt->next->next;free(fbt->next);free(fbt);}//左分区可合并else if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}//右分区可合并else if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//左分区不存在else if(0==pre->size) {if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//右分区不存在else if(NULL==fbt->next) {if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}}rearrange(algorithm);free(head);return 1;}int dispose(struct allocated_block *free_ab){struct allocated_block *pre, *ab;if(free_ab == allocated_block_head) {allocated_block_head = allocated_block_head->next;free(free_ab);return 1;}pre = allocated_block_head;ab = allocated_block_head->next;while(ab!=free_ab){ pre = ab; ab = ab->next; }pre->next = ab->next;free(ab);return 2;}int display_mem_usage(){struct free_block_type *fbt=free_block;struct allocated_block *ab=allocated_block_head;if(fbt==NULL) return(-1);printf("----------------------------------------------------------\n");printf("Free Memory:\n");printf(" s s\n", " start_addr", " size");while(fbt!=NULL){printf(" d d\n", fbt->start_addr, fbt->size);fbt=fbt->next;}printf("\nUsed Memory:\n");printf("s s s s\n", "PID", "ProcessName", "start_addr", " size");while(ab!=NULL){printf("d s d d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);ab=ab->next;}printf("----------------------------------------------------------\n");return 0;}void do_exit() {}。

操作系统 动态分区存储管理

操作系统 动态分区存储管理

实验四动态分区存储管理实验目的:熟悉并掌握动态分区分配的各种算法。

熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。

实验内容:用高级语言模拟实现动态分区存储管理,要求:1、分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至少一种。

熟悉并掌握各种算法的空闲区组织方式。

2、分区的初始化——可以由用户输入初始分区的大小。

(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小)3、分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。

4、分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。

(注意:不存在的作业号要给出错误提示!)5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)6、要求考虑:(1)内存空间不足的情况,要有相应的显示;(2)作业不能同名,但是删除后可以再用这个名字;(3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。

#include "iostream.h"#include "iomanip.h"#define ERR_NOFREEAREA 1#define ERR_NOADEQUACYAREA 2#define ERR_ALLOCATED 4#define ERR_NOJOBS 1#define ERR_NOSUCHJOB 2#define ERR_RECLAIMED 4typedef struct tagUsedNode{long address;long length;int flag;//作业名struct tagUsedNode *next;}USED_AREA, *USED_TABLE;typedef struct tagFreeNode{long address;long length;struct tagFreeNode *next;}FREE_AREA, *FREE_TABLE;//空闲区、作业区链表USED_TABLE usedTable=NULL;FREE_TABLE freeTable=NULL;//给作业分配空间int Allocate(int jobname,long jobsize){//如果没有空闲区if(freeTable==NULL)return ERR_NOFREEAREA;FREE_TABLE p=freeTable;FREE_TABLE q=p;//找首次适应空闲区while(p!=NULL&&p->length<jobsize){q=p;p=p->next;}//如果找不到有足够空间的分区if(p==NULL)return ERR_NOADEQUACYAREA;USED_TABLE x=new USED_AREA;x->address=p->address;x->length=jobsize;x->flag=jobname;x->next=NULL;//如果该分区大于作业需求,空间大小减去作业大小if(p->length>jobsize){p->length-=jobsize;p->address+=jobsize;}//如果该分区等于作业大小,删除该分区else{if( p==freeTable)freeTable=NULL;elseq->next=p->next;delete p;}//作业加入"作业表"中USED_TABLE r=usedTable;USED_TABLE t=r;while(r!=NULL&&r->address<x->address) {t=r;r=r->next;}if(usedTable==NULL)usedTable=x;else{x->next=r;t->next=x;}return ERR_ALLOCATED;}//回收作业空间int Reclaim(int jobname){if(usedTable==NULL)return ERR_NOJOBS;USED_TABLE p=usedTable;USED_TABLE q=p;while(p!=NULL&&p->flag!=jobname) {q=p;p=p->next;}//如果没有该作业if(p==NULL)return ERR_NOSUCHJOB;//回收后的空间加入到空闲区FREE_TABLE r=freeTable;FREE_TABLE t=r;FREE_TABLE x;while(r!=NULL&&r->address<p->address) {t=r;r=r->next;}x=new FREE_AREA;x->address=p->address;x->length=p->length;x->next=NULL;if(r==freeTable ){x->next=r;freeTable=x;t=freeTable;}else{x->next=r;t->next=x;}//合并分区while(t->next!=NULL&&t->address+t->length==t->next->address) {t->length+=t->next->length;r=t->next;t->next=t->next->next;delete r;}//删除作业if( p==usedTable){usedTable=usedTable->next;}elseq->next=p->next;delete p;return ERR_RECLAIMED;}int Init(){freeTable=new FREE_AREA;freeTable->address=0;freeTable->length=1024;freeTable->next=NULL;return 1;}void jobrequest(){int jobname;int jobsize;cout<<"\n************************"<<endl;cout<<"作业名: ";cin>>jobname;cout<<"作业长度: ";cin>>jobsize;if(Allocate(jobname,jobsize)==ERR_ALLOCATED)cout<<"该作业已成功获得所需空间"<<endl;elsecout<<"该作业没有获得所需空间"<<endl;cout<<"************************\n"<<endl;}void jobreclaim(){int jobname;cout<<"\n************************"<<endl;cout<<"作业名: ";cin >>jobname;int result=Reclaim(jobname);if(result==ERR_RECLAIMED)cout<<"该作业已成功回收"<<endl;else if(result==ERR_NOSUCHJOB||result==ERR_NOJOBS)cout<<"该作业不存在,请重新输入"<<endl;cout<<"************************\n"<<endl;}void freeTablePrint(){cout<<"\n*****************************************"<<endl;cout<<setw(10)<<"地址"<<setw(10)<<"大小"<<setw(10)<<"状态"<<endl<<endl;FREE_TABLE p=freeTable;USED_TABLE q=usedTable;int x,y;while(p||q){if(p)x=p->address;elsex=0x7fffffff;if(q)y=q->address;elsey=0x7fffffff;if(x<y){cout<<setw(10)<<p->address<<setw(10)<<p->length<<setw(10)<<"空闲"<<endl;p=p->next;}if(x>y){cout<<setw(10)<<q->address<<setw(10)<<q->length<<setw(10)<<"已分配"<<setw(10)<<"ID="<<q->flag<<endl;q = q->next;}}cout<<"*****************************************\n"<<endl;}void main(){Init();int choose;bool exitFlag = false;while(!exitFlag){cout<<"-----------------------输入选择项-----------------------"<<endl;cout<<"------ 1 分配分区 2 回收分区 3 显示分区 4 退出------"<<endl;cout<<"--------------------------------------------------------\n"<<endl;cout<<"选择: ";cin>>choose;switch(choose){break;case 1:jobrequest();break;case 2:jobreclaim();break;case 3:freeTablePrint();break;case 4:exitFlag=true;}}}。

动态分区算法实验报告

动态分区算法实验报告

动态分区算法实验报告动态分区算法实验报告一、引言计算机操作系统是现代计算机系统中的核心组成部分,它负责管理计算机硬件资源,并提供各种服务。

内存管理是操作系统的重要功能之一,它负责管理计算机的内存资源,为进程提供运行环境。

在内存管理中,动态分区算法是一种常用的内存分配策略。

本实验旨在通过实践,深入了解动态分区算法的原理和实现。

二、实验目的1. 了解动态分区算法的基本原理和实现方式;2. 掌握动态分区算法的实验环境搭建和使用方法;3. 分析动态分区算法的优缺点,并比较不同算法的性能差异。

三、实验环境本实验使用C语言编程实现,实验环境如下:1. 操作系统:Windows 10;2. 开发工具:Visual Studio 2019;3. 编程语言:C语言。

四、实验过程1. 实验准备在开始实验之前,我们首先需要了解动态分区算法的基本原理。

动态分区算法根据进程的内存需求,将内存划分为若干个不同大小的分区,并按照进程的请求进行分配和释放。

常用的动态分区算法有首次适应算法、最佳适应算法和最坏适应算法等。

2. 实验设计本实验选择实现首次适应算法,并设计以下几个函数:- 初始化内存空间:初始化一块指定大小的内存空间,将其划分为一个个的分区,并设置分区的状态;- 分配内存:根据进程的内存需求,在内存空间中找到合适的分区进行分配,并更新分区的状态;- 释放内存:将已分配的内存空间进行释放,并更新分区的状态;- 显示内存状态:打印当前内存空间的分区状态。

3. 实验实现根据上述设计,我们使用C语言实现了动态分区算法的相关函数。

通过调用这些函数,我们可以模拟动态分区算法的运行过程,并观察分区的分配和释放情况。

4. 实验结果经过实验,我们得到了以下结果:- 动态分区算法可以有效地管理内存资源,根据进程的需求进行灵活的内存分配;- 首次适应算法在内存分配效率和速度方面表现良好,但可能会导致内存碎片的产生;- 释放内存时,及时合并相邻的空闲分区可以减少内存碎片的数量。

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

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

实验题目:存储器内存分配设计思路: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:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。

实验四 操作系统存储管理实验报告

实验四  操作系统存储管理实验报告

实验四操作系统存储管理实验报告一、实验目的本次操作系统存储管理实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配、回收、地址转换等关键技术,提高对操作系统存储管理机制的认识和应用能力。

二、实验环境操作系统:Windows 10开发工具:Visual Studio 2019三、实验原理1、内存分配方式连续分配:分为单一连续分配和分区式分配(固定分区和动态分区)。

离散分配:分页存储管理、分段存储管理、段页式存储管理。

2、内存回收算法首次适应算法:从内存低地址开始查找,找到第一个满足要求的空闲分区进行分配。

最佳适应算法:选择大小最接近作业需求的空闲分区进行分配。

最坏适应算法:选择最大的空闲分区进行分配。

3、地址转换逻辑地址到物理地址的转换:在分页存储管理中,通过页表实现;在分段存储管理中,通过段表实现。

四、实验内容及步骤1、连续内存分配实验设计一个简单的内存分配程序,模拟固定分区和动态分区两种分配方式。

输入作业的大小和请求分配的分区类型,程序输出分配的结果(成功或失败)以及分配后的内存状态。

2、内存回收实验在上述连续内存分配实验的基础上,添加内存回收功能。

输入要回收的作业号,程序执行回收操作,并输出回收后的内存状态。

3、离散内存分配实验实现分页存储管理的地址转换功能。

输入逻辑地址,程序计算并输出对应的物理地址。

4、存储管理算法比较实验分别使用首次适应算法、最佳适应算法和最坏适应算法进行内存分配和回收操作。

记录不同算法在不同作业序列下的内存利用率和分配时间,比较它们的性能。

五、实验结果与分析1、连续内存分配实验结果固定分区分配方式:在固定分区大小的情况下,对于作业大小小于或等于分区大小的请求能够成功分配,否则分配失败。

内存状态显示清晰,分区的使用和空闲情况一目了然。

动态分区分配方式:能够根据作业的大小动态地分配内存,但容易产生内存碎片。

2、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。

动态分区管理方式及动态分区算法

动态分区管理方式及动态分区算法

动态分区管理方式及动态分区算法一、动态分区概述在操作系统中,内存管理是一个非常重要的部分。

在实际的应用中,程序的内存需求是会发生变化的,因此需要一种灵活的内存管理方式来满足不同程序的内存需求。

动态分区管理方式应运而生,它可以根据程序的需求,灵活地分配和回收内存空间,是一种高效的内存管理方式。

二、动态分区管理方式动态分区管理方式是指将内存划分为多个大小不等的分区,每个分区都可以被分配给进程使用,当进程终止时,分区将被回收。

动态分区管理方式通常通过动态分区算法来实现,下面将介绍几种常见的动态分区算法。

三、首次适应算法首次适应算法是最简单和最直观的动态分区分配算法。

它的基本思想是在空闲分区链表中按照位置区域顺序查找第一个能够满足进程大小需求的空闲分区,并将其分配给进程。

首次适应算法的优点是实现简单,分区利用率较高,但缺点是会产生大量的不连续碎片。

四、最佳适应算法最佳适应算法是在空闲分区链表中查找满足进程大小需求的最小空闲分区,并将其分配给进程。

最佳适应算法的优点是可以减少外部碎片,缺点是查找适合的空闲分区会花费较长的时间。

五、最坏适应算法最坏适应算法是在空闲分区链表中查找满足进程大小需求的最大空闲分区,并将其分配给进程。

最坏适应算法的优点是能够产生较小的碎片,但缺点是会导致剩余分区较多,影响分区利用率。

六、动态分区管理方式的优缺点动态分区管理方式相比于静态分区管理方式有很多优点,比如可以灵活地满足不同程序的内存需求,可以动态地合并和分割分区,提高了内存的利用率等。

但是动态分区管理方式也有一些缺点,比如会产生碎片,分配和回收内存的开销较大等。

七、结语动态分区管理方式及其算法在实际应用中有着广泛的应用,通过合理选择动态分区算法,可以提高内存的利用率,改善系统性能。

也需要注意动态分区管理方式可能产生的碎片问题,可以通过内存紧缩等手段来解决。

希望本文对读者有所帮助。

动态分区管理方式及动态分区算法八、碎片问题与解决方法在动态分区管理方式中,经常会出现碎片问题,包括内部碎片和外部碎片。

动态分区分配操作系统操作方法实验步骤

动态分区分配操作系统操作方法实验步骤

动态分区分配操作系统操作方法实验步骤1.引言1.1 概述概述部分:在计算机系统中,动态分区分配是一种重要的操作系统操作方法。

它是指在运行时根据进程的内存需求动态地将系统内存分配给进程,以实现内存资源的高效利用。

动态分区分配操作方法在现代操作系统中被广泛应用,例如Windows、Linux等。

通过合理的动态分区分配策略,可以提升系统的性能和资源利用率。

本文将对动态分区分配操作系统操作方法进行详细介绍和实验步骤的说明。

首先,我们将介绍动态分区分配的背景和意义,包括其在操作系统中的作用和应用场景。

其次,我们将详细讨论实验的具体步骤,包括如何进行动态分区分配操作、如何测试相关的性能指标等。

本文的目标是帮助读者了解动态分区分配操作系统操作方法的基本原理和实践技巧。

同时,通过实际操作和实验验证,读者将能够更好地理解动态分区分配的概念和操作过程,提升对操作系统的理解和应用能力。

在接下来的章节中,我们将分别介绍动态分区分配操作系统操作方法的背景和实验步骤,并给出相应的实例和案例分析。

最后,我们将对实验结果进行总结和展望,探讨动态分区分配操作方法的发展前景和可能的研究方向。

通过本文的阅读和实验操作,读者将能够对动态分区分配操作系统操作方法有一个全面的了解,为进一步研究和应用提供基础和指导。

同时,我们也欢迎读者对本文内容进行补充和扩展,以促进相关领域的进一步发展和应用。

1.2 文章结构文章结构部分的内容可以从以下角度进行描述:文章结构是指整篇文章的组织框架和内容安排。

合理的文章结构可以使读者更好地理解文章的主题和内容,帮助读者快速找到所需信息并形成完整的认识。

本文将按照以下结构进行论述:1. 引言:在引言部分,我们将对动态分区分配操作系统操作方法的背景和意义进行介绍,明确文章的目的和重要性。

2. 正文:正文是文章的核心部分,将分为两个要点进行叙述。

2.1 第一个要点:动态分区分配操作系统操作方法。

首先,我们将对动态分区分配的背景进行介绍,解释其在操作系统中的应用和意义。

动态分区分配方式使用的数据结构和分配算法

动态分区分配方式使用的数据结构和分配算法

动态分区分配方式使用的数据结构和分配算法一、引言动态分区分配是操作系统中常用的内存管理方式之一,它的主要目的是为了有效地利用计算机内存资源。

在动态分区分配中,操作系统会将可用内存空间划分为多个大小不同的连续空间,然后按照进程请求的大小来进行动态地分配和释放。

这种方式可以避免内存浪费,提高内存利用率,同时也能够保证进程访问内存时的安全性和稳定性。

二、数据结构在动态分区分配中,需要使用两个重要的数据结构:空闲块链表和已占用块链表。

1. 空闲块链表空闲块链表是指所有未被占用的内存块组成的链表。

每个节点表示一个可用块,并包含以下信息:- 块大小:表示该节点对应空闲块的大小。

- 起始地址:表示该节点对应空闲块在内存中的起始地址。

- 链接指针:指向下一个可用块节点。

2. 已占用块链表已占用块链表是指所有被进程占用的内存块组成的链表。

每个节点表示一个已占用块,并包含以下信息:- 块大小:表示该节点对应已占用块的大小。

- 进程ID:表示该节点对应已占用块所属的进程ID。

- 起始地址:表示该节点对应已占用块在内存中的起始地址。

- 链接指针:指向下一个已占用块节点。

三、分配算法动态分区分配中常用的算法有“首次适应算法”、“最佳适应算法”、“最差适应算法”等。

1. 首次适应算法首次适应算法是指从空闲块链表头开始,依次查找第一个能够满足请求大小的空闲块,并将其分配给进程。

这种方式可以快速地找到满足条件的空闲块,但可能会留下一些无法利用的小碎片。

2. 最佳适应算法最佳适应算法是指从所有可用空闲块中选择大小最合适的空闲块进行分配。

这种方式可以尽可能地利用内存资源,但需要遍历所有可用空闲块,效率较低。

3. 最差适应算法最差适应算法是指从所有可用空闲块中选择大小最大的空闲块进行分配。

这种方式可以尽可能地避免留下碎片,但也可能导致大量内存浪费。

四、动态分区分配的优缺点动态分区分配方式具有以下优点:- 可以动态地分配和释放内存,避免了内存浪费。

动态分区分配算法

动态分区分配算法

计算机操作系统动态分区磁盘调度算法一个好的计算机系统不仅要有足够的存储容量,较高的存取速度和稳定可靠的存储器,而且能够合理的分配和使用这些主存空间。

当用户提出申请主存空间的要求时,存储管理能够按照一定的策略分析主存的使用情况,找出足够的空间分配给申请者;当作业运行完毕,存储管理要回收作业占用的主存空间。

本实验采取可变分区存储管理方法,用常用分区管理算法模拟磁盘管理过程,以加深了解操作系统的存储管理功能。

1. 本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。

2. 采用最先适应法、最佳适应法、最坏适应法分配主存空间。

3. 当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。

若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。

4. 当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。

5. 设计的模拟系统中,进程数不小于5,进程调度方式可以采用实验一中的任何一种。

6. 运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。

首次适应算法将内存中的空闲区按照地址由低到高的顺序形成空闲区表当一个新作业要求装入主存时,查空闲区表,从中找到第一个满足要求的空闲区,为作业分配主存空间,并将剩余空闲区按照地址由小到大的顺序插入空闲区表的合适位置,修改已分配表当作业运行结束后,回收作业的主存空间,并与相邻空闲区合并,修改空闲区表和已分配表每次主存分配和回收后,打印空闲区表和已分配表详细描述实验设计思想、程序结构及各模块设计思路;详细描述程序所用数据结构及算法;明确给出测试用例和实验结果;为增加程序可读性,在程序中进行适当注释说明;认真进行实验总结,包括:设计中遇到的问题、解决方法与收获等;#include<iostream>#include<cstdlib>using namespace std;const int procsize=5;typedef struct Node{int PId; //进程Idint Prio; //进程优先数int NeedRunTime; //进程需要运行时间int Room; //进程所需空间大小Node * next; //就绪队列中的下个就绪进程的地址}PCB;typedef struct{ //就绪链式队列结构体PCB *front;PCB *rear;}AleadyQueue;typedef struct Tab{ //分区表结构体int CalledId; //调用该分区的进程Idint TabId; //分区号int Size; //大小int StartAdd; //始址char * Status; //使用状态Tab *next; //指向下个分区}Table;void CinInfo(PCB P[procsize]){ //输入进程信息cout<<"\t\t请输入5个进程,格式如下:\n\n ";cout<<"PId 优先数运行时间所需内存大小(最好是小于20)\n";int i=0,j=0;for(i,j; i<procsize ; i++,j++){cin>>P[j].PId>>P[j].Prio>>P[j].NeedRunTime>>P[j].Room;}}void Sort(PCB P[procsize]){ //根据优先数由冒泡法对进程进行排序int i,j,exchange=1; //exchange表示相邻PCB是否调换PCB Temp;for(i=procsize;i>1&&exchange;i--){exchange=0;for(j=0;j<i-1;j++)if(P[j].Prio<P[j+1].Prio){Temp=P[j];P[j]=P[j+1];P[j+1]=Temp;exchange=1;}}}AleadyQueue InitQueue(){ //就绪队列初始化函数AleadyQueue Q;Node *p;p=(Node *)malloc(sizeof(PCB));if(!p){cout<<"就绪队列初始化失败!\n";exit(0);}else{Q.front=Q.rear=p;Q.front->next=NULL;return Q;}}void EnQueue(AleadyQueue &Queue,PCB &P){ //进程入队操作函数Node *p;p=(Node *)malloc(sizeof(PCB));if(!p)cout<<"分配节点失败!\n";else {*p=P;p->next=NULL;Queue.rear->next=p;Queue.rear=p;}}void EnQueue1(AleadyQueue &Queue,PCB &P){ //进程入队操作函数Node *p;p=(Node *)malloc(sizeof(PCB));if(!p)cout<<"分配节点失败!\n";else {*p=P;p->next=NULL;Queue.rear->next=p;Queue.rear=p;}}PCB OutQueue(AleadyQueue &Q){ //进程出队操作函数Node *P;P=(Node *)malloc(sizeof(PCB));if(Q.front->next!=NULL){P=Q.front->next;Q.front->next=P->next;}return *P;}PCB OutQueue1(AleadyQueue &Q){ //进程出队操作函数Node *P;P=(Node *)malloc(sizeof(PCB));if(Q.front->next!=NULL){P=Q.front->next;Q.front->next=P->next;}return *P;}void printinfo(AleadyQueue Q){ //打印就绪队列的情况cout<<"目前就绪队列进程情况如下:\n";cout<<"PId\t\tPriority\t\tNeedTime\t\tRoom\n";Q.front=Q.front->next;while(1){if(Q.front!=NULL){cout<<Q.front->PId<<"\t\t"<<Q.front->Prio<<"\t\t\t";cout<<Q.front->NeedRunTime<<"\t\t\t"<<Q.front->Room<<endl;Q.front=Q.front->next;}elsebreak;}}int chose(){ //选择所选算法int i;cout<<"请选择:\n";cout<<" 1、采用<首次适应>算法为进程分配内存!\n";cout<<" 2、采用<最佳适应>算法为进程分配内存!\n";cout<<" 3、采用<最坏适应>算法为进程分配内存!\n";cout<<" 4、结束!\n";cin>>i;return i;}Table * CreateMMTable(){ //定义主存分区表Table * FT; //用尾插入法Table * R;Table * P;FT=(Table *)malloc(sizeof(Tab));R=FT;FT->next=NULL;int num=0;int LastAdd=0;int LastSize=1;while(1){P=(Table *)malloc(sizeof(Tab));P->CalledId=0; //被调用的进程调Id初始化为0P->TabId=num; //主存分区号P->Size=3*num+1; //分区大小P->StartAdd=LastAdd+LastSize; //分区始址P->Status="Free"; //分区状态num++; //分区号加1LastAdd=P->StartAdd; //重新定义LastAdd为上次的StartAddLastSize=P->Size; //同上P->next=NULL;R->next=P;R=P;if(P->StartAdd==93) //内存初始化完毕break;}return FT;}Table * CreateUsedTable(){ //创建已分配表Table * T;T=(Table *)malloc(sizeof(Tab));T->next=NULL;return T;}void CoutMMTable(Table * FTL){ //打印主存表情况cout<<"主存表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";FTL=FTL->next;while(1){cout<<FTL->TabId<<"\t\t"<<FTL->StartAdd<<"\t\t";cout<<FTL->Size<<"\t\t";cout<<FTL->Status<<endl;FTL=FTL->next;if(FTL->next==NULL)break;}}void CoutFreeTable(Table * FTL){ //打印空闲区表cout<<"空闲区表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";FTL=FTL->next;while(1){cout<<FTL->TabId<<"\t\t"<<FTL->StartAdd<<"\t\t";cout<<FTL->Size<<"\t\t";printf("%s\n",FTL->Status);FTL=FTL->next;if(FTL->next==NULL)break;}}void CoutUsedTable(Table * UTL){ //打印已分配表cout<<"已分配表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";UTL=UTL->next;while(1){if(UTL->Status=="Used"){cout<<UTL->TabId<<"\t\t"<<UTL->StartAdd<<"\t\t";cout<<UTL->Size<<"\t\t";printf("%s\n",UTL->Status);}UTL=UTL->next;if(UTL->next==NULL)break;}}int DistribMM(Table * MMTableList,PCB Temp,Table * FTL,Table * UTL){//分配一块一定大小的内存Table *P;Table * TempMM; //需要改为已分配节点的上一个节点TempMM=MMTableList;Table * TTT;TTT=MMTableList->next;while(1){ //查找满足大小的分区节点if(TTT->Size>=Temp.Room && TTT->Status=="Free")break;TTT=TTT->next;if(TTT==NULL){cout<<"\n\n\n\t\t\t\t警告!内存不足....\n\n\n";return 0;}}//while//以下是内存改为已分配P=(Table *)malloc(sizeof(Tab));while(1){if(TempMM->next==TTT)break;TempMM=TempMM->next;}P->next=TempMM->next;TempMM->next=P;P->StartAdd=TTT->StartAdd;P->Size=Temp.Room;P->CalledId=Temp.PId;P->TabId=TTT->TabId;P->Status="Used";P=P->next;while(P!=NULL){(P->TabId)++;P=P->next;}FTL=FTL->next;while(1){ //将空闲分区对应的首地址更改if(FTL->StartAdd==TTT->StartAdd)break;FTL=FTL->next;}TTT->StartAdd=FTL->StartAdd=TTT->StartAdd+Temp.Room;//空闲表的首地址=原来+Room TTT->Size=FTL->Size=TTT->Size-Temp.Room;while(FTL!=NULL){(FTL->TabId)++;FTL=FTL->next;}return 2;}void ReturnMM(Table * MMTableList,Table * FTL,Table * UTL,PCB &Temp){ //回收一块内存MMTableList=MMTableList->next;FTL=FTL->next;Table *TT;while(1){if(MMTableList->CalledId==Temp.PId){if(MMTableList->next->Status=="Free"){MMTableList->Status="Free"; //修改内存,相邻的为FreeMMTableList->CalledId=0;MMTableList->Size=MMTableList->Size+MMTableList->next->Size;MMTableList->next=MMTableList->next->next;TT=MMTableList;while(FTL!=NULL){if(FTL->StartAdd==TT->next->StartAdd)break;FTL=FTL->next;}FTL->Size=TT->Size;}if(MMTableList->next->Status!="Free"){MMTableList->Status="Free"; //修改内存,相邻的为USedMMTableList->CalledId=0;while(FTL!=NULL){if(FTL->StartAdd==TT->next->StartAdd)break;FTL=FTL->next;}FTL->Size=TT->Size;}}if(MMTableList->next==NULL)break;MMTableList=MMTableList->next;}//总whilecout<<"\n";}int FF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q){ //首次适应算法PCB Temp;int i; //记录分配函数的返回值0int num=0; //记录进程首次分配内存while(1){Temp=OutQueue(Q);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0; //内存不足CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==1){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==2){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0; // printf("y余朝水\n");CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==3){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==4){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";if(Temp.PId==5)return 1;ReturnMM(MMTableList,FTL,UTL,Temp); //回收内存CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表printinfo(Q);if(Q.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue(Q,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 2;}int BF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q2){ //最佳适应算法PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组PQ2=InitQueue(); //就绪队列初始化for(int k=0; k<procsize; k++)EnQueue(Q2,P[k]);int i; //记录分配函数的返回值0int num=0;PCB Temp;while(1){Temp=OutQueue1(Q2);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==1){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==2){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==3){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==4){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";cout<<"...........................\n\n";if(Q2.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue1(Q2,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 1;}int WF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q2){ //最坏适应算法PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组P Q2=InitQueue(); //就绪队列初始化for(int k=0; k<procsize; k++)EnQueue(Q2,P[k]);int i; //记录分配函数的返回值0int num=0;PCB Temp;while(1){Temp=OutQueue1(Q2);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==1){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==2){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==3){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==4){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";cout<<"...........................\n\n";if(Q2.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue1(Q2,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 2;}void main(){AleadyQueue Q1; //定义一个就绪队列AleadyQueue Q2;AleadyQueue Q3;PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组P Q1=InitQueue(); //就绪队列初始化Q2=InitQueue();Q3=InitQueue();for(int k=0; k<procsize; k++)EnQueue(Q1,P[k]); //首次排好序的就绪进程入队,//进程依次等待处理机调度for(k=0; k<procsize; k++)EnQueue(Q2,P[k]);for(k=0; k<procsize; k++)EnQueue(Q3,P[k]);printinfo(Q1); //打印当前就绪队列的情况Q3=Q2=Q1;Table * MMTableList; //主存分区表Table * MM;Table * FreeTableList; //空闲分区表Table * UsedTableList; //已分配分区表MMTableList=CreateMMTable(); //创建主存分区表MM=CreateMMTable();FreeTableList=CreateMMTable(); //创建空闲分区表(初始化时和内存分区表相同)UsedTableList=CreateUsedTable(); //创建已分配表CoutMMTable(MMTableList); //打印主存分区表int i; //记录0,内存不足int j; //记录所选算法while(1){j=chose(); //判断所选算法,所需操作(FF、BF、WF)if(j==1)i=FF(MM,FreeTableList,UsedTableList,Q1);//首次适应算法if(i==0)exit(0); //内存不足if(j==2)i=BF(MM,FreeTableList,UsedTableList,Q2);//最佳适应算法if(i==0)exit(0); //内存不足if(j==3)i=WF(MM,FreeTableList,UsedTableList,Q3);//最坏适应算法if(i==0)exit(0); //内存不足if(j==4)break; //结束内存分配}cout<<"\n\n\n-----------------------------------欢迎使用!------------------------------------\n\n\n\n\n"; }。

计算机操作系统实验报告动态分区分配方式的模拟

计算机操作系统实验报告动态分区分配方式的模拟

计算机操作系统实验报告姓名:班级:学号:题目:动态分区分配方式的模拟实习内容简要描述本次实验要完成两部分内容:一是用C语言实现对采用首次适应算法和最佳适应算法的动态分区分配过程ALLOCo和回收过程FREE(),其中空闲分区由空闲分区链来管理,进行分配时,系统优先使用空闲区底端空间。

二是假设初始状态下,可用内存空间为640KBO按照题目要求的作业顺序,以及各个作业分配和回收的内存空间。

分别采用首次适应法和最佳适应法,对内存进行分配和回收,要求每次分配和回收后显示空闲内存分区链的情况。

实验分析算法介绍本次实验通过用C语言进行编程并调试、运行,形象地表现出动态分区的分配方式,直观地展现了首次适应算法和最佳适应算法对内存的释放和回收方式之间的区别。

加深了我们对两种算法优缺点的理解,帮助我们了解一些数据结构和分配算法,进一步加深我们对动态分区存储器管理方式及其实现过程的理解。

主要的问题在于,如何解决两种算法对内存的释放和回收空间的表示。

动态分区分配:又称为可变分区分配,这种分配方式并不事先先将主存划分成一块块的分区,而是在作业进入主存时,根据作业的大小动态地建立分区。

并使分区的大小正好适应作业的需要。

因此系统中分区的大小是可变的,分区的数目也是可变的。

分区分配算法:(两者的空闲块链接方式不冋)①首次适应法:为作业选择分区时总是按地址从高到低搜索,只要找到可以容纳该作业的空白块,就把该空白块分配给该作业。

特点:优先利用内存中底地址部分的空闲分区(将所有空闲区,按其地址递增的顺序链接)②最佳适应算法:接到内存申请时,在空闲块表中找到一个不小于请求的最小空块进行分配;为作业选择分区时总是寻找其大小最接近于作业所要求的存储区域。

特点:用最小空间满足要求(将所有空闲区,按其大小递增的顺序联接成空闲区链)结果分析(思考题解答;错误原因分析)间的分配和回收。

思考题解答:1、首次适应算法分配时从表头指针开始查找可利用空间表,将找到的第一个大小不小于“请求”的空闲块的一部分分配给用户。

(完整word版)动态分区分配方式的模拟实验报告

(完整word版)动态分区分配方式的模拟实验报告

L[i].sad=L[i]。sad+T[k]。rom;
L[i]。rom=L[i].rom—T[k].rom;
L[i]。state=1;
T[k].sad=L[i].sad—T[k].rom;
printf("内存分配成功!\n作业申请空间为%d\n起始地址为%d\n”,T[k].rom,T[k]。sad);
L[i]。rom=L[i].rom-T[k].rom;
L[i].state=1;
T[k]。sad=L[i]。sad-T[k]。rom;
printf("内存分配成功!\n作业申请空间为%d\n起始地址为%d\n",T[k]。rom,T[k].sad);
break;

else

L[i]。sad=L[i]。sad+Size;
4。实验原理或流程图
首次适应算法(First-fit):当要分配内存空间时,就查表,在各空闲区中查找满足大小要求的可用块。只要找到第一个足以满足要球的空闲块就停止查找,并把它分配出去;如果该空闲空间与所需空间大小一样,则从空闲表中取消该项;如果还有剩余,则余下的部分仍留在空闲表中,但应修改分区大小和分区始址。
L[i].rom=L[i]。rom-Size;
L[i]。state=2;
T[k]。sad=L[i].sad—Size;
printf(”内存分配成功!\n作业申请空间为%d\n起始地址为%d\n",L[i]。rom,T[k].sad);
break;
}
}
else if(L[i].state=0&&L[i]。rom—T[k]。rom==Size)
T[k].id=k;
int i;

操作系统内存动态分配模拟算法

操作系统内存动态分配模拟算法

操作系统内存动态分配模拟算法操作系统内存动态分配是操作系统对内存资源进行合理分配和管理的一种技术。

其实质是根据程序的需求,将物理内存分割成若干个大小相等的内存块,然后将程序的逻辑地址空间映射到这些内存块上。

这样,程序将感觉到它拥有整个内存的使用权,而实际上其实只能访问到被映射的内存块。

常见的内存动态分配算法包括首次适配、最佳适配和最坏适配等。

下面将分别介绍这几种算法的原理和优缺点。

首次适配算法(First Fit)是指将第一个满足程序要求大小的空闲内存块分配给程序。

这种算法的实现较为简单,仅需遍历整个内存块链表即可。

然而,由于首次适配分配的是满足要求的第一个内存块,因此可能会导致形成大量的碎片空间,从而减少了可用内存的利用率。

最佳适配算法(Best Fit)是指在所有满足程序要求大小的空闲内存块中选择最小的一个分配给程序。

这种算法比首次适配算法更加合理,能够充分利用碎片空间,提高内存的利用率。

然而,由于需要遍历所有的空闲内存块,因此算法的性能相对较低。

最坏适配算法(Worst Fit)是指在所有满足程序要求大小的空闲内存块中选择最大的一个分配给程序。

这种算法的主要目的是为了降低外部碎片的产生。

但是,由于内存块的分配更加倾向于大的空闲块,因此可能导致大量的小碎片空间,从而增加了再分配的开销和运行时的内存碎片整理。

此外,还有一种较为常见的内存动态分配算法是循环首次适配算法(Circular First Fit)。

其与首次适配算法类似,但其从上一次分配的位置开始,不会每次都从链表的头部开始,从而缩小了的范围,提高了算法的性能。

总结来说,不同的内存动态分配算法有着各自的优缺点。

首次适配算法简单易实现,但会产生大量碎片空间;最佳适配算法能够提高内存利用率,但性能较低;最坏适配算法能够降低外部碎片的产生,但会增加小碎片空间。

因此,在实际应用中,需要根据具体的场景和需求选择合适的算法来进行内存动态分配,以达到最优的资源利用效率。

动态分区分配方式使用的数据结构和分配算法

动态分区分配方式使用的数据结构和分配算法

动态分区分配方式使用的数据结构和分配算法1. 引言动态分区分配方式是操作系统中一种常用的内存管理方式,它将内存划分为多个动态大小的分区,根据程序的需要进行动态分配和释放。

本文将介绍动态分区分配方式使用的数据结构和分配算法。

2. 数据结构在动态分区分配方式中,需要使用以下数据结构来管理内存空间:2.1 空闲块链表空闲块链表是一个双向链表,用于记录当前可用的内存空间。

每个节点表示一个空闲块,包含以下字段: - 起始地址:表示该空闲块在内存中的起始地址。

- 大小:表示该空闲块的大小。

- 前驱指针:指向前一个空闲块节点。

- 后继指针:指向后一个空闲块节点。

通过维护这个链表,可以高效地查找和管理可用的内存空间。

2.2 分配表分配表是一个数组,用于记录当前已经被程序占用的内存空间。

每个元素表示一个已经被占用的内存块,包含以下字段: - 起始地址:表示该内存块在内存中的起始地址。

- 大小:表示该内存块的大小。

- 进程ID:表示占用该内存块的进程ID。

通过维护这个数组,可以方便地查找和管理已经被程序占用的内存空间。

3. 分配算法在动态分区分配方式中,需要使用一种合适的算法来进行内存分配。

常用的分配算法有以下几种:3.1 首次适应算法(First Fit)首次适应算法是最简单和最常用的分配算法之一。

它从空闲块链表中找到第一个大小大于等于所需大小的空闲块,并将其分割成两部分,一部分满足程序需求,另一部分仍然是空闲块。

该算法具有以下特点: - 实现简单,时间复杂度较低。

- 分配效率较高,但可能会导致碎片问题。

3.2 最佳适应算法(Best Fit)最佳适应算法是一种比较高效的分配算法。

它从空闲块链表中找到大小最接近所需大小的空闲块,并将其分割成两部分。

该算法具有以下特点: - 分配效果较好,能够尽量减少碎片问题。

- 时间复杂度较高,需要遍历整个空闲块链表。

3.3 最坏适应算法(Worst Fit)最坏适应算法是一种相对较差的分配算法。

计算机操作系统课程设计报告《存储管理——动态分区分配算法的模拟》

计算机操作系统课程设计报告《存储管理——动态分区分配算法的模拟》

《计算机操作系统》课程设计题目:存储管理——动态分区分配算法的模拟专业:软件工程年级:2012级小组成员:指导教师:时间:地点:2012年5 月目录目录 (1)概述 (3)2. 课程设计任务及要求 (3)2.1 设计任务 (3)2.2 设计要求 (3)2.3 课程设计任务安排 (3)3. 算法及数据结构 (4)3.1算法的总体思想(流程) (4)3.2首次适应算法 (4)3.2.1 功能 (4)3.2.2 数据结构(包括变量的定义,要注释!) (4)3.2.3 算法(流程图表示,或伪C表示) (5)3.3循环首次适应算法 (6)3.3.1功能 (6)3.3.2 数据结构 (6)3.3.3算法 (7)3.4最佳适应算法 (8)3.4.1功能 (8)3.4.2 数据结构 (8)3.4.3算法 (8)3.5最坏适应算法 (10)3.5.1功能 (10)3.5.2 数据结构 (10)3.5.3算法 (11)4. 程序设计与实现 (12)4.1 程序流程图 (12)4.2 程序代码(要注释) (12)4.3 实验结果 (21)5. 结论 (23)6. 收获、体会和建议。

(23)A的总结: (23)B的总结: (23)7. 参考文献。

(24)概述动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。

在本实验中运用了五种分配算法,分别是:1.首次适应算法2.循环首次适应算法3.最坏适应算法4.最佳适应算法5. 快速适应算法2. 课程设计任务及要求2.1设计任务要求设计主界面以灵活选择其中算法,5种算法都要求实现。

2.2设计要求1)首先由系统生成当前的内存状态,要求未分配的分区数量不少于3个,且空间大小随机,然后随机生成一个数,表示等待分配进程的大小。

2)然后显示上述算法由用户选择,结果显示分配后的状态。

3. 算法及数据结构3.1算法的总体思想(流程)设计程序模拟四种动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的工作过程。

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

操作系统实验四【实验题目】:动态分区分配算法【实验学时】:4学时【实验目的】通过这次实验,加深对动态分区分配算法的理解,进一步掌握首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的实现方法。

【实验内容及要求】问题描述:设计程序模拟四种动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的工作过程。

假设内存中空闲分区个数为n,空闲分区大小分别为P1, … ,P n,在动态分区分配过程中需要分配的进程个数为m(m≤n),它们需要的分区大小分别为S1, …,S m,分别利用四种动态分区分配算法将m个进程放入n个空闲分区,给出进程在空闲分区中的分配情况。

程序要求:1)利用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法四种动态分区分配算法模拟分区分配过程。

2)模拟四种算法的分区分配过程,给出每种算法进程在空闲分区中的分配情况。

3)输入:空闲分区个数n,空闲分区大小P1, … ,P n,进程个数m,进程需要的分区大小S1, … ,S m。

4)输出:首次适应算法,循环首次适应算法,最佳适应算法,最坏适应算法,最终内存空闲分区的分配情况。

实现源代码:#include<iostream>#include<fstream>#include<iomanip>#include<string>#define max 100using namespace std;int work_num;int zone_num;struct Data{int data;char name;};Data *d=new Data[max];struct Table{int data;char array[max];int length;};Table *T=new Table[max];Table *temp=new Table[max];void Init(){ifstream inf("DTFQ.txt");int i,j;char ch;inf>>work_num;cout<<"作业数:"<<work_num<<endl;inf>>zone_num;cout<<"空闲分区数:"<<zone_num<<endl;cout<<" 作业为:";for(j=0;j<work_num;j++){inf.get(ch);d[j].name=ch;cout<<setw(4)<<d[j].name;}cout<<endl;cout<<"作业大小:";for(i=0;i<work_num;i++){inf>>d[i].data;cout<<setw(4)<<d[i].data;}cout<<endl;cout<<"空闲分区:";for(j=0;j<zone_num;j++){inf>>T[j].data;temp[j].data=T[j].data;T[j].length=0;temp[j].length=0;cout<<setw(4)<<T[j].data;}cout<<endl;}void renew(){int j;for(j=0;j<zone_num;j++){T[j].data=temp[j].data;T[j].length=temp[j].length;}}void re(){int i;for(i=0;i<zone_num;i++){T[i].array[T[i].length]='#';}}void show(){int i,j;re();for(i=0;i<zone_num;i++){if(T[i].data==temp[i].data)cout<<setw(4)<<T[i].data;else{cout<<setiosflags(ios::right)<<setw(4)<<T[i].data<<setw(1);for(j=0;j<T[i].length;j++){if(T[i].array[j]=='#')break;elsecout<<setiosflags(ios::right)<<T[i].array[j];}}}cout<<endl;}void first_fit(){renew();cout<<"fist fit:";int i,j;int tag=0;for(i=0;i<work_num;i++){for(j=0;j<zone_num;j++){if(d[i].data<=T[j].data){T[j].data=T[j].data - d[i].data;T[j].array[T[j].length]=d[i].name;T[j].length++;tag=0;break;}elsetag=1;}if(tag==1){cout<<"作业太大,无满足条件分区!"<<endl;break;}}//re();}void next_fit(){renew();cout<<"next fit:";int i,j;int m=0,tag=0,count=0;for(i=0;i<work_num;i++){for(j=m;j<zone_num;j++){if(d[i].data<=T[j].data){T[j].data=T[j].data - d[i].data;T[j].array[T[j].length]=d[i].name;T[j].length++;tag=0;m=j;break;}else{tag=1;count++;}}while(tag==1 && count<zone_num){for(j=0;j<m;j++){if(d[i].data<=T[j].data){T[j].data=T[j].data - d[i].data;T[j].array[T[j].length]=d[i].name;T[j].length++;tag=0;break;}else{tag=1;count++;}}}if(tag==1 && count==zone_num){cout<<"作业太大,无满足条件分区!"<<endl;break;}}//re();}void best_fit(){renew();cout<<"best fit:";int i,j,k,temp,m;int tag=0,n=0;for(i=0;i<work_num;i++){for(j=0;j<zone_num;j++){if(d[i].data<=T[j].data){temp=T[j].data;m=j;int tag1=0;for(k=m+1;k<=zone_num;k++){if(T[k].data<temp){if(T[k].data>=d[i].data){temp=T[k].data;n=k;tag1=1;}}else if(tag1==0)n=j;}T[n].data=temp - d[i].data;T[n].array[T[n].length]=d[i].name;T[n].length++;tag=0;break;}elsetag=1;}if(tag==1){cout<<"作业太大,无满足条件分区!"<<endl;break;}}//re();}void worst_fit(){renew();cout<<"worst fit:";int i,j,k,temp,m;int tag=0,n=0;for(i=0;i<work_num;i++){for(j=0;j<zone_num;j++){if(d[i].data<=T[j].data){int tag1=0;temp=T[j].data;m=j;for(k=m+1;k<=zone_num;k++){if(T[k].data>temp){if(T[k].data>=d[i].data){temp=T[k].data;n=k;tag1=1;}}else if(tag1==0)n=j;}T[n].data=temp - d[i].data;T[n].array[T[n].length]=d[i].name;T[n].length++;tag=0;break;}elsetag=1;}if(tag==1){cout<<"作业太大,无满足条件分区!"<<endl;break;}}//re();}void main(){Init();first_fit();show();next_fit();show();best_fit();show();worst_fit();show();system("pause");}实验截图:。

相关文档
最新文档