实验三动态分区存储管理方式的主

合集下载

动态分区存储管理方式的主存分配回收总结

动态分区存储管理方式的主存分配回收总结

动态分区存储管理方式的主存分配回收总结动态分区存储管理是一种常见的主存分配回收技术,它通过动态创建并分配大小不等的存储块来管理主存空间,以满足不同进程的需求。

这种管理方式在操作系统中起着至关重要的作用,因此本文将对动态分区存储管理的主存分配回收进行总结,从原理、特点、优缺点及其在实际应用中的情况进行阐述。

一、原理动态分区存储管理是基于分区的主存管理机制,它将主存空间划分为多个不等大小的分区,每个分区可以被分配给一个进程使用。

当系统收到一个新进程的请求时,它会根据需要的主存大小为进程分配一个合适大小的分区。

当进程执行完毕,系统会回收该进程所占用的分区,使得该空间可以再次被分配给其他进程使用。

在动态分区存储管理中,主要有两种分配方式:首次适应算法和最佳适应算法。

首次适应算法是从第一个满足大小要求的分区开始进行分配;而最佳适应算法是从所有满足大小要求的分区中选择最小的分区进行分配。

这两种分配方式都有自己的优点和局限性,但它们都是基于动态分区存储管理的基本原理。

二、特点1.灵活性动态分区存储管理可以根据进程的需求动态地分配和回收主存空间,提高了主存的利用率和效率。

进程可以根据需要申请和释放主存空间,而无需预先分配固定大小的空间。

2.节省空间动态分区存储管理可以尽可能地利用主存中的碎片空间,减少了外部碎片的浪费。

这种管理方式能够充分利用主存空间,提高了主存的利用率。

3.多样性动态分区存储管理可以适应不同大小的进程需求,能够根据进程的大小灵活地进行分区分配,满足了不同进程的需求。

三、优缺点1.优点(1)提高了主存的利用率和效率。

(2)灵活地分配和回收主存空间,满足不同进程的需求。

(3)节省了主存空间,减少了碎片的浪费。

2.缺点(1)会产生外部碎片,影响了分区空间的利用率。

(2)分配和回收过程中可能产生较大的开销,影响了系统的性能。

四、在实际应用中的情况动态分区存储管理在操作系统中得到了广泛的应用,特别是在多道程序设计和实时系统中。

动态分区分配存储管理系统

动态分区分配存储管理系统

动态分区分配存储管理系统一、设计目的与内容用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法1)首次适应算法2)循环首次适应算法1.内存中有0-100M的空间为用户程序空间,最开始用户空间是空闲的。

2.作业数量、作业大小、进入内存时间、运行时间需要通过界面进行输入。

3.可读取样例数据(要求存放在外部文件中)进行作业数量、作业大小、进入内存时间、运行时间的初始化。

4.根据作业进入内存的时间,采用简单的先进先出原则进行从外存到内存的调度,作业具有等待(从外存进入内存执行)、装入(在内存可执行)、结束(运行结束,退出内存)三种状态。

5.能够自动进行内存分配与回收,可根据需要自动进行紧凑与拼接操作。

二、算法的基本思想1、定义基本结构:1作业结构:typedefstructJOB{intnum;//作业号intsize;//作业大小intctime;//作业进入时间intrtime;//作业运行时间intstate;//作业状态}Job;2)分区结构:typedefstructDuLNode{intID;//分区号intstart;//开始地址intsize;//大小intstate;//0=尚未使用1=使用2=释放structDuLNode*prior;〃前驱指针structDuLNode*next;//后即指针}DuLNode,*DuLinkList;2、基本操作:intFirstfit(int);//首次适应算法intNext_fit(int);//循环首次适应算法voidshowJob(int);//显示作业表voidshowPartiton(DuLinkList);//显示分区表DuLinkListInitpartitionList(DuLinkList&p);//初始化voidhuishou(DuLinkListpl3,DuLinkList&pl);//回收函数intPutin(int&口);//输入函数,输入作业相关信息3、首次适应算法空闲分区链以地址递增的次序链接,分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,取消的空闲分区仍留在空闲链中。

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

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

实验题目:存储器内存分配设计思路: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.紧凑:通过移动内存中作业的位置,以把原来多个分散的小分区拼接成一个大分区的方法。

三、实验内容与步骤1.打开程序,所得程序界面窗口如图3-1:图3-12.首先选择算法:是否使用搬家算法,可以通过界面上的按钮或算法菜单栏进行选择;如果不先选择算法,其他功能将被隐藏;注意:在程序执行过程中,不可以重新选择算法。

3.进行初始化:设置内存大小,可以选择默认值400KB;确定内存大小前,其他操作将被屏蔽。

4.初始化内存大小以后,就可以进行添加进程操作。

5.添加一个进程后,撤消进程功能被激活,可以撤消一个选定的进程或所有的进程(图3-2)图3-26.查询功能:可以通过按钮或菜单栏显示内存状态图形、空闲区图表,还可以在内存状态条里闪烁显示某一在空闲区图表选中的空闲区。

7.内存不足但经过搬家算法可以分配内存空间给进程,将有如下(图3-3)提示:图3-38.内存空间不足也有相应提示。

9.重置或退出。

四、实验结果第一组数据:内存大小300K,三个进程分配情况为:60K,50K,80K,不采用搬家算法第二组数据:内存大小500K,五个进程分配情况为:60K,80K,20K,70K,300K,不采用搬家算法第三组数据:内存大小400K,6个进程分配情况为:30K,90K,20K,50K,70K,80K,分配好以后删除第三个,第五个进程,再为第七个进程分配100K,不采用搬家算法第四组数据:内存大小300K,三个进程分配情况为:60K,50K,80K,采用搬家算法第五组数据:内存大小500K,五个进程分配情况为:60K,80K,20K,70K,300K,采用搬家算法第六组数据:内存大小400K,6个进程分配情况为:30K,90K,20K,50K,70K,80K,分配好以后删除第三个,第五个进程,再为第七个进程分配100K,采用搬家算法第七组数据大家自行设计,不采用搬家算法,但不能全部分配第八组数据与第七组数据相同,但采用搬家算法后可以全部分配。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

动态分区分配存储管理系统

动态分区分配存储管理系统

动态分区分配存储管理系统学院专业学号学生姓名指导老师2014年3月19日目录一、设计目的与内容 (1)1、设计目的 (3)2、设计内容 (3)3、设计要求 (3)二、算法的基本思想 (3)1、首次适应算法 (3)2、循环首次适应算法 (3)三、主要功能模块流程图 (4)1、主函数流程图.......................................................... 、42、首次适应算法流程图.................................................... 、53、循环首次适应算法流程图................................................ 、6四、系统测试................................................................. 、7输入界面,按要求输入: (7)五、结论 (8)六、源程序 (9)一、设计目的与内容设计的目的操作系统课程设计就是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识与实际有机的结合起来,独立分析与解决实际问题的机会。

●进一步巩固与复习操作系统的基础知识。

●培养学生结构化程序、模块化程序设计的方法与能力。

●提高学生调试程序的技巧与软件设计的能力。

●提高学生分析问题、解决问题以及综合利用 C 语言进行程序设计的能力。

设计内容:用高级语言编写与调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法1.首次适应算法2.循环首次适应算法设计要求:1.内存中有0-100M 的空间为用户程序空间,最开始用户空间就是空闲的2.作业数量、作业大小、进入内存时间、运行时间需要通过界面进行输入3.可读取样例数据(要求存放在外部文件中)进行作业数量、作业大小、进入内存时间、运行时间的初始化4.根据作业进入内存的时间,采用简单的先进先出原则进行从外存到内存的调度,作业具有等待(从外存进入内存执行)、装入(在内存可执行)、结束(运行结束,退出内存)三种状态。

操作系统实验3-动态分区存储管理

操作系统实验3-动态分区存储管理

实验三动态分区存储管理一:实验目的了解动态分区存储管理方式中的数据结构和分配算法,加深对动态分区存储管理方式及其实现技术的理解。

二:实验内容用C语言或Pascal语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程Allocate()和回收过程Free()。

其中,空闲分区采用空闲分区链来组织,内存分配时,优先使用空闲区低地址部分的空间。

三:实验类别动态分区存储管理四:实验类型模拟实验五:主要仪器计算机六:结果和小结七:程序#include<stdio.h>#include<time.h>#include<stdlib.h>#define SIZE 640 // 内存初始大小#define MINSIZE 5 // 碎片最小值struct memory{struct memory *former;//前向指针int address;//地址int num;//作业号int size;//分配内存大小int state;//状态0表示空闲,1表示已分配struct memory *next;//后向指针}linklist;void intmemory()// 初始化空闲分区链{memory *p=(memory *)malloc(sizeof(memory));// 分配初始分区内存p->address=0;// 给首个分区赋值p->size=SIZE;p->state=0;p->num=-1;p->former=&linklist;p->next=NULL;linklist.former=NULL;// 初始化分区头部信息linklist.next=p;}int firstFit(int num, int size)// 首次适应算法{memory *p = linklist.next;while(p != NULL){if(p->state == 0 && p->size >= size) // 找到要分配的空闲分区{if(p->size - size <= MINSIZE)// 整块分配{p->state = 1;p->num = num;}else // 分配大小为size的区间{memory *node=(memory *)malloc(sizeof(memory));node->address=p->address + size;node->size=p->size-size;node->state=0;node->num=-1;// 修改分区链节点指针node->former=p;node->next=p->next;if(p->next !=NULL){p->next->former=node;}p->next = node;// 分配空闲区间p->size = size;p->state = 1;p->num = num;}printf("内存分配成功!\n");return 1;}p = p->next;}printf("找不到合适的内存分区,分配失败...\n");return 0;}int bestFit(int num, int size)// 最佳适应算法{memory *tar=NULL;int tarSize=SIZE + 1;memory *p=linklist.next;while(p!=NULL){if(p->state==0 && p->size >= size && p->size < tarSize) //寻找最佳空闲区间{tar=p;tarSize=p->size;}p=p->next;}if(tar!=NULL){if(tar->size - size <= MINSIZE) //找到要分配的空闲分区{tar->state = 1;// 整块分配tar->num=num;}else // 分配大小为size的区间{memory *node = (memory *)malloc(sizeof(memory));node->address = tar->address + size;node->size = tar->size - size;node->state = 0;node->num = -1;// 修改分区链节点指针node->former = tar;node->next = tar->next;if(tar->next != NULL){tar->next->former = node;}tar->next = node;// 分配空闲区间tar->size = size;tar->state = 1;tar->num = num;}printf("内存分配成功!\n");return 1;} else{// 找不到合适的空闲分区printf("找不到合适的内存分区,分配失败!!\n");return 0;}}int freememory(int num)// 回收内存{int flag=0;memory *p=linklist.next, *pp;while(p!=NULL){if(p->state==1 && p->num==num){flag = 1;if((p->former!= &linklist && p->former->state == 0) && (p->next != NULL && p->next->state == 0)){// 情况1:合并上下两个分区// 先合并上区间pp=p;p=p->former;p->size+=pp->size;p->next=pp->next;pp->next->former=p;free(pp);// 后合并下区间pp=p->next;p->size+=pp->size;p->next=pp->next;if(pp->next!=NULL){pp->next->former=p;}free(pp);}else if((p->former==&linklist || p->former->state==1)&& (p->next!=NULL&&p->next->state ==0)) {// 情况2:只合并下面的分区pp=p->next;p->size+=pp->size;p->state=0;p->num=-1;p->next=pp->next;if(pp->next!= NULL){pp->next->former=p;}free(pp);}else if((p->former!=&linklist&&p->former->state==0)&& (p->next==NULL || p->next->state==1)) {// 情况3:只合并上面的分区pp=p;p=p->former;p->size+=pp->size;p->next=pp->next;if(pp->next != NULL) {pp->next->former = p;}free(pp);}else{// 情况4:上下分区均不用合并p->state=0;p->num=-1;}}p=p->next;}if(flag==1){// 回收成功printf("内存分区回收成功...\n");return 1;}else{// 找不到目标作业,回收失败printf("找不到目标作业,内存分区回收失败...\n");return 0;}}// 显示空闲分区链情况void showmemory(){printf(" 当前的内存分配情况如下:\n");printf("*********************************************\n");printf(" 起始地址| 空间大小| 工作状态| 作业号\n");memory *p=linklist.next;while(p!=NULL){printf("******************************************\n");printf("**");printf("%5d k |", p->address);printf("%5d k |", p->size);printf(" %5s |", p->state == 0 ? "0" : "1");if(p->num > 0) {printf("%5d ", p->num);} else {printf(" ");}p = p->next;}}int main(){int option, ope, num, size;// 初始化空闲分区链intmemory();// 选择分配算法l1: while(1){printf("***************************************\n");printf("请选择要模拟的分配算法:\n1表示首次适应算法\n2表示最佳适应算法\n");printf("***************************************\n");scanf("%d", &option);system("cls");if(option==1) {printf("你选择了首次适应算法,下面进行算法的模拟\n");break;} else if(option==2) {printf("你选择了最佳适应算法,下面进行算法的模拟\n");break;}else {printf("错误:请输入0/1\n\n");}}// 模拟动态分区分配算法while(1){printf("\n");printf("*********************************************\n");printf("1:分配内存\n 2:回收内存\n 3:返回上一级菜单\n\n");printf("*********************************************\n");scanf("%d", &ope);system("cls");if(ope==0) break;if(ope==1){// 模拟分配内存printf("请输入作业号:");scanf("%d", &num);printf("请输入需要分配的内存大小(KB):");scanf("%d", &size);if(size<=0){printf("错误:分配内存大小必须为正值\n");continue;}// 调用分配算法if(option==0){firstFit(num, size);}else{bestFit(num, size);}// 显示空闲分区链情况showmemory();}else if(ope==2){// 模拟回收内存printf("请输入要回收的作业号:");scanf("%d", &num);freememory(num);// 显示空闲分区链情况showmemory();}else if(ope==3){goto l1;}else{printf("错误:请输入0/1/2\n");}}printf("分配算法模拟结束\n");return 0;}。

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

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

计算机操作系统实验报告实验二实验题目:存储器管理系别:计算机科学与技术系班级:姓名:学号:2一、实验目的深入理解动态分区存储管理方式下的内存空间的分配与回收。

二、实验内容编写程序完成动态分区存储管理方式下的内存分配和回收的实现。

具体内容包括:确定用来管理内存当前使用情况的数据结构;采用首次适应算法完成内存空间的分配;分情况对作业进行回收;编写主函数对所做工作进行测试。

三、实验原理分配:动态分区存储管理方式把内存除OS占用区域外的空间看作一个大的空闲区。

当作业要求装入内存时,根据作业需要内存空间的大小查询内存中各个空闲区,当从内存中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业要求划出一个分区装入该作业。

回收:作业执行完后,它所占用的内存空间被收回,成为一个空闲区。

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

四、实验方法实现动态分区的分配与回收,主要考虑三个问题:第一、设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域(利用结构体类型数组来保存数据);第二、在设计的数据表格基础上设计内存分配算法(采用首次适应算法找合适的分区(对空闲分区表进行排序),分配时要考虑碎片问题);第三、在设计的数据表格基础上设计内存回收算法(分四种情况进行回收(上邻、下邻、上下邻和无相邻分区)。

五、实验步骤第一,设计记录内存使用情况的数据表格●已分配分区表:起始地址、长度、标志(0表示“空表项”,1表示“已分配”)●空闲分区表:起始地址、长度、标志(0表示“空表项”,1表示“未分配”)struct used_table {float address; //已分分区起始地址float length; //已分分区长度,单位为字节int flag; //已分配表区登记栏标志,用0表示空栏目,char zuoyename;}; //已分配区表Struct free_table[ {float address; //空闲分区起始地址float length; //空闲分区长度,单位为字节int flag; //空闲分区表登记栏目用0表示空栏目,1表示未配}; //空闲分区表第二,在设计的表格上进行内存分配●首次适应算法:为作业分配内存,要求每次找到一个起始地址最小的适合作业的分区(按起始地址递增排序)。

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

实验三动态分区存储管理方式的主存分配回收一、实验目的深入了解动态分区存储管理方式主存分配回收的实现。

二、实验预备知识存储管理中动态分区的管理方式。

三、实验内容编写程序完成动态分区存储管理方式的主存分配回收的实现。

实验具体包括:首先确定主存空间分配表;然后采用最优适应算法完成主存空间的分配和回收;最后编写主函数对所做工作进行测试。

四、提示与讲解动态分区管理方式预先不将主存划分成几个区域,而把主存除操作系统占用区域外的空间看作一个大的空闲区。

当作业要求装入主存时,根据作业需要主存空间的大小查询主存内各个空闲区,当从主存空间中找到一个大于或等于该作业大小的主存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装入该作业。

作业执行完后,它所占的主存分区被收回,成为一个空闲区。

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

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

首先,考虑第一个问题:设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域。

由于动态分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收变动。

总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。

由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。

由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。

主存分配时查找空闲区进行分配,然后填写已分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。

由此可见,主存的分配和回收主要是对空闲区的操作。

这样为了便于对主存空间的分配和回收,就建立两张分区表记录主存使用情况,一张表格记录作业占用分区的“已分配区表”;一张是记录空闲区的“空闲区表”。

这两张表的实现方法一般有两种,一种是链表形式,一种是顺序表形式。

在实验中,采用顺序表形式,用数组模拟。

由于顺序表的长度必须提前固定,所以无论是“已分配区表”还是“空闲区表”都必须事先确定长度。

它们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因而在多数情况下,无论是“已分配区表”还是“空闲区表”都有空闲栏目。

已分配区表中除了分区起始地址、长度外,也至少还要有一项“标志”,如果是空闲栏目,内容为“空”,如果为某个作业占用分区的登记项,内容为该作业的作业名;空闲区表中除了分区起始地址、长度外,也要有一项“标志”,如果是空闲栏目,内容为“空”,如果为某个空闲区的登记项,内容为“未分配”。

在实际系统中,这两表格的内容可能还要多,实验中仅仅使用上述必须的数据。

为此, “已分配区表”和“空闲区表”在实验中有如下的结构定义。

已分配区表的定义:#define n 10// 假定系统允许的最大作业数量为nstruct{float address;// 已分分区起始地址float length; // 已分分区长度,单位为字节int flag;// 已分配区表登记栏标志, “0表”示空栏目,实验中只支持一个字符的作业名}used_table[n];// 已分配区表空闲区表的定义:#define m 10// 假定系统允许的空闲区表最大为mstruct{float address;// 空闲区起始地址float length;// 空闲区长度,单位为字节int flag;// 空闲区表登记栏标志,用“ 0表”示空栏目,用“ 1表”示未分配}free_table[m];// 空闲区表其中分区起始地址和长度数值太大,超出了整型表达范围,所以采用了float 类型。

然后,就要考虑如何在设计的数据表格上进行主存的分配。

当要装入一个作业时,从空闲区表中查找标志为“未分配”的空闲区,从中找出一个能容纳该作业的空闲区。

如果找到的空闲区正好等于该作业的长度,则把该分区全部分配给作业。

这时应该把该空闲区登记栏中的标志改为“空”,同时在已分配区表中找到一个标志为“空”的栏目登记新装入作业所占用分区的起始地址、长度和作业名。

如果找到的空闲区大于作业长度,则把空闲区分成两部分,一部分用来装入作业,另外一部分仍为空闲区。

这时只要修改原空闲区的长度,且把新装入的作业登记到已分配区表中。

实验中主存分配算法采用“最优适应”算法。

最优适应算法是按作业要求挑选一个能满足作业要求的最小空闲区,这样保证可以不去分割一个大的区域,使装入大作业时比较容易得到满足。

但是最优适应算法容易出现找到的一个分区可能只比作业所要求的长度略大一点的情况,这时,空闲区分割后剩下的空闲区就很小,这种很小的空闲区往往无法使用,影响了主存的使用。

为了一定程度上解决这个问题,如果空闲区的大小比作业要求的长度略大一点,不再将空闲区分成已分分区和空闲区两部分,而是将整个空闲区分配给作业。

在实现最优适应算法时,可把空闲区按长度以递增方式登记在空闲区表中。

分配时顺序查找空闲表,查找到的第一个空闲区就是满足作业要求的最小分区。

这样查找速度快,但是为使空闲区按长度以递增顺序登记在空闲表中,就必须在分配回收时进行空闲区表的调整。

空闲区表调整时移动表目的代价要高于查询整张表的代价,所以实验中不采用空闲区有序登记在空闲表中的方法。

动态分区方式的主存分配流程如图4所示。

作业J申请xk大小的主存空间i=0;k=-1;i 是空闲区表中一栏(i<=m)?YN第i 栏标志为“未分配”且满足作业需求xk?N是否找到满足需求的分区k?N 主存分配失败结束YY第k 栏xx-作业需求≤minsiz?e N第i 栏空闲区为第一个满足需求的或第i 栏空闲区xx小于第k 栏空闲区xx?N 分配整个分区:第k 栏状态为“空ad=第k栏起始地址;xk=第k 栏xx;Yi=0切割空闲区:第k 栏xx 减去xk;ad=第k栏起始地址- 第k 栏xx;k=i i=i+1第i 栏是已分配区表中一栏且第i 栏状态不为空?i=i+1YNY第i 栏是为已分分配表中一栏?YN填写已分配区表:第j 栏起始地址=ad;第j 栏xx=xk;第j 栏状态=作业名J 空闲区表第k 栏状态为空?N 空闲区表状态未分配空闲区表第k栏长度加xk 已分配区表长度不足,分配失败结束图4 动态分区最优分配算法流程图最后是动态分区方式下的主存回收问题。

动态分区方式下回收主存空间时,应该检查是否有与归还区相邻的空闲区。

若有,则应该合并成一个空闲区。

一个归还区可能有上邻空闲区,也可能有下邻空闲区,或者既有上邻空闲区又有下邻空闲区,或者既无上邻空闲区也无下邻空闲区。

在实现回收时,首先将作业归还的区域在已分配表中找到,将该栏目的状态变为“空”,然后检查空闲区表中标志为“未分配”的栏目,查找是否有相邻空闲区;最后,合并空闲区,修改空闲区表。

假定作业归还的分区起始地址为S,长度为L,则:(1)归还区有下邻空闲区如果S+L正好等于空闲区表中某个登记栏目(假定为第j 栏)的起始地址,则表明归还区有一个下邻空闲区。

这时只要修改第j 栏登记项的内容:起始地址=S;第j 栏xx=第j 栏xx+L;则第j 栏指示的空闲区是归还区和下邻空闲区合并后的大空闲区。

(2)归还区有上邻空闲区如果空闲区表中某个登记栏目(假定为第k栏)的“起始地址+长度”正好等于S,则表明归还区有一个上邻空闲区。

这时要修改第k 栏登记项的内容(起始地址不变):第k 栏xx=第k 栏xx+L;于是第k 栏指示的空闲区是归还区和上邻空闲区合并后的大空闲区。

(3)归还区既有上邻空闲区又有下邻空闲区如果S+L正好等于空闲区表中某个登记栏目(假定为第j 栏)的起始地址,同时还有某个登记栏目(假定为第k栏)的“起始地址+长度”正好等于S,这表明归还区既有一个上邻空闲区又有一个下邻空闲区。

此时对空闲区表的修改如下:第k 栏长度=第k 栏长度+第j 栏长度+L;(第k 栏起始地址不变)第j 栏状态=“空”;(将第j 栏登记项删除)这样,第k 栏指示的空闲区是归还区和上、下邻空闲区合并后的大空闲区;原来的下邻空闲区登记项(第j 栏)被删除,置为“空”。

(4)归还区既无上邻空闲区又无下邻空闲区如果在检查空闲区表时,无上述三种情况出现,则表明归还区既无上邻空闲区又无下邻空闲区。

这时,应该在空闲区表中查找一个状态为“空”的栏目(假定查到的是第t 栏),则第t 栏的内容修改如下:第t 栏起始地址=S;第t 栏xx=L;第t 栏状态=“未分配”这样,第t 栏指示的空闲区是归还区。

按上述方法归还主存区域的流程如图5 所示。

由于是实验,没有真正的主存要分配,所以在实验中,首先应建立一张空闲区表,初始状态只有一个空闲登记项(假定的主存空闲区)和一张所有状态都为“空”的已分配区表,假定主存空间110KB,操作系统占用10KB,其余为空闲区;然后,可以选择进行主存分配或主存回收,如果是分配,要求输入作业名和所需主存空间大小,如果是回收,输入回收作业的作业名,循环进行主存分配和回收后,如果需要,则显示两张表的内容,以检查主存的分配和回收是否正确。

作业J 归还空间s=0s=s+1已分配区表第s 栏状态为作业J(s<=n)?NYNs 为已分配区表中一栏?YS=已分配区表第Ys 栏起始地址L=已分配区表第s 栏xx已分配区表第s 栏状态为空未找到作业,回收失败结束假设下邻空闲区在第假设上邻空闲区在第i=0j 栏j=-1;k栏k=-1;i=i+1第i栏不是空闲区表中一栏或回收分区的上下邻空闲区均找到?YNN第i 栏状态为“未分配”?YY回收分区有上邻?N 回收分区有下邻?N 回收分区有下邻?Nt=0YYY第i 栏为回收分区的上邻?NY j=i 第Ni 栏为回收分区的下邻?NY 第t 栏是空闲表一栏?N 和上邻合并:第k 栏xx= 第k 栏xx+L 和上下邻三项合并:第k 栏xx=第k 栏长度+第j栏xx+L;第j 栏状态=“空”和下邻合并:第j 栏长度=第j栏长度+L第j 栏起始地址=Sj=i t=t+1 第t 栏是空闲表xx 空栏?YN 已分配区表第s 栏状态为J;空闲区表xx 不足,回收失败归还分区填入空闲区表:第t 栏起始地址=S;第t 栏xx=L;第t 栏状态=“未分配”结束图5 动态分区回收流程图五、课外题(1)编程实现页式存储管理的主存分配和回收。

(2)用链表方式表示主存空间分配情况,完成动态分区管理方式下的主存空间分配和回收。

相关文档
最新文档