计算机操作系统内存分配实验报告记录

合集下载

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

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

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

实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。

二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。

三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。

在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。

2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。

为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。

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

同样通过对空闲分区链表的排序和查找来实现。

(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。

在模拟过程中,使用一个队列来记录页面的进入顺序。

2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。

通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。

3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。

四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。

2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。

3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。

操作系统 主存储器空间分配实验

操作系统 主存储器空间分配实验

学生实验报告(课程名称:操作系统)实验题目:主存储器空间分配实验一、实验目的通过首次适应算法、最佳适应算法和最坏适应算法实现主存空间的分配,可以使读者可好地理解存储分配算法。

二、实验环境VC++三、实验内容与要求编写一段程序来模拟可变分区管理方法。

要求能通过文件形式定义空闲区表;能随意输入作业及需要分配的空间;能分别使用首次适应算法、最佳适应算法和最坏适应算法对输入的作业进行空间分配;能显示系统空闲表和已分配空间表。

⑴可变分区方式是按作业需要的主存空间大小来分区。

当装入一个作业时,首先要查看是否有足够的空闲空间来分配,若有则按指定的分配方式进行分配;否则作业不能装入。

随着作业的装入和撤离主存空间被分为若干个大大小小的不连续的区间,为了表明各区间的状态可以用一个内存分区表如表1所示来表示。

表1 内存分区表起始地址长度标志120k 20k 作业1200k 50k 空闲这样我们可以定义一个如下的结构表示内存分区信息。

typedef struct node{int start; //起始地址int length; //长度char tag[20]; //标志}job;⑵可变分区的三种算法就是为作业分配主存空间的方法。

●首次适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入第一个满足条件的空间中去。

●最佳适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入满足条件的空闲空间中最小的一个空间中去。

●最坏适应算法:在空闲区间中查询满足作业需要的空间,并将作业装入满足条件的空闲空间中最大的一个空间中去。

从三种算法的说明可以看出,分配空间的过程主要可以分两步:●查询所有满足作业需求的空间块。

●按照指定的算法将作业装入空间块中。

⑶在操作的最初主存空间实际就是一个大的空闲区,不涉及到如何分配的问题。

为直接模拟运行一段时间后主存中出现了多个空闲块的状态,题目要求从一个文件读入空闲区表。

在这里我们可以设计一个空闲区表文件的结构为如表2所示:表2 空闲区表起始地址长度200k 50k……这样也可以方便地将空闲表一次读入程序中,而不必再一个个的输入。

主内存空间分配和恢复实验报告.doc

主内存空间分配和恢复实验报告.doc

主内存空间分配和恢复实验报告。

操作系统实验报告实验[1]:主存储空间的分配和名字的恢复;贺兰雪诺。

以下内容:201306080215专业课:132次实验时间:2015.5.31报告时间:2015.6.6分类:计算机科学学院:电气与信息工程学院实验三中主存储空间的分配与恢复I .为实验内容分配和恢复主存储空间。

第二,实验目的一个好的计算机系统不仅要有足够的容量、高速的访问速度、稳定可靠的主存,还要能够合理地分配和使用这些存储空间。

当用户申请内存空间时,内存管理必须根据申请人的要求,按照一定的策略分析主内存空间的使用情况,并找出足够的空闲空间分配给申请人。

当作业收回或主动返回主内存资源时,存储管理将回收作业占用的主内存空间或返回部分主内存空间。

主存分配和恢复的实现与主存的管理模式有关。

本实验帮助学生理解如何在可变分区管理模式下实现主存空间的分配和恢复。

第三,实验原理仿真采用第一种自适应算法实现可变分区管理模式下的内存分配和恢复。

(1)可变分区方法根据作业所需的主内存空间大小划分分区。

当要加载作业时,根据作业所需的主库存检查是否有足够的可用空间,如果有,根据所需的数量划分分区并分配给作业;否则,无法加载作业。

随着作业的加载和卸载,主内存空间被分成许多分区,其中一些被作业占用,一些是空闲的。

例如:05k10k14k26k32k512k操作系统作业1作业3自由区域作业2自由区域为了解释哪些区域是自由的,可以用来加载新作业,必须有一个自由区域描述表,格式如下:起始地址长度状态的第一列14 K12 K没有被分配,第二列32 K96 K没有被分配给MMMM,其中起始地址——指示空闲区域的主存储器起始地址。

长度——表示从起始地址开始的连续空闲长度。

状态——有两种状态,一种是“未分配”状态,这表示由起始地址指示的某一长度的相应区域是空闲区域。

(2)当新作业需要加载到主存储器中时,必须检查空闲区域描述表以找到足够大的空闲区域。

操作系统-内存分配与回收实验报告

操作系统-内存分配与回收实验报告

操作系统-内存分配与回收实验报告本次实验是关于内存管理的实验,主要涉及内存分配和回收的操作。

本文将对实验过程和结果进行详细介绍。

1. 实验目的本次实验的主要目的是熟悉内存管理的基本原理和机制,掌握内存分配和回收的方法,并且实现一个简单的内存管理器。

2. 实验原理内存管理是操作系统的重要组成部分,主要负责管理计算机的内存资源,并且协调进程对内存的访问。

在计算机工作过程中,内存扮演着重要的角色,因此内存管理的效率和稳定性对计算机的性能和稳定性有着重要影响。

内存管理包括内存分配和回收两个方面。

内存分配是指为进程分配空闲的内存空间,以便程序可以执行;内存回收是指将已经使用完成的内存空间还回给系统,以便其他进程使用。

3. 实验步骤为了实现一个简单的内存管理器,我们需要进行以下步骤:(1)定义内存块结构体首先,我们需要定义一个内存块结构体,用于描述内存块的基本信息。

内存块结构体可以包含以下信息:· 内存块的起始地址· 内存块是否被分配下面是一个内存块结构体定义的示例代码:typedef struct mem_block{void *start_address; // 内存块的起始地址size_t size; // 内存块的大小bool is_allocated; // 内存块是否已经分配}MemBlock;(3)实现内存分配函数现在,我们可以开始实现内存分配函数了。

内存分配函数需要完成以下工作:· 在内存管理器中寻找一个合适的内存块void *mem_alloc(MemManager *manager, size_t size){MemBlock *p = manager->block_list;while(p){if(p->size >= size && !p->is_allocated){p->is_allocated = true;return p->start_address;}p = p->next;}return NULL;}· 找到该内存块所在的位置· 将该内存块标记为未分配状态4. 实验结果本次实验实现了一个简单的内存管理器,通过该内存管理器可以实现内存分配和回收的操作。

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

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

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

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

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

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

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

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

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

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

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

操作系统实验报告11-系统内存使用统计

操作系统实验报告11-系统内存使用统计

《操作系统》实验报告实验序号:11实验项目名称:系统内存使用统计/ * Allocate space for a pat name * /string=malloc( MAX PATH); //分配内存空间if(string==NULL)prinf(“Insufficient memory available\n”);else{printf(“Memory space allocated for path name\n”):free(string);printf(“Memory free \n”);}3、实验要求能正确使用系统函数GlobalMemoryStatus()和数据结构MEMORYSTATUS 了解系统内存和虚拟存储空间使用情况,会使用VirtualAlloc()函数VirtualFree()函数分配和释放虚拟存储空间。

4、实验指导在Microsoft Visual C++6.0环境下选择Win32 Console Application 建立一个控制台工程文件,由于内存分配、释放及系统存储空间使用情况函数均是Microsoft Windows操作系统的系统调用,因此需要选择An application that supports MFC。

四、程序调试(结果及分析)运行代码截图如下图1-1:图1-1 运行结果截图如下图1-2:图1-2五、总结与体会总结、体会该实验是实现进程间的信息传递的,是由客户端与服务端之间进行通信的。

其中要实现客户端与服务端之间的通信,需要同时打开客户端与服务端的窗口,在客户端的编辑框输入信息,点击发送信息,则信息发送到服务端,点击确定则关闭客户端(服务端)。

六、教师评语成绩签名:。

操作系统内存分配实验报告

操作系统内存分配实验报告

操作系统实验报告内存分配学生学号:学生姓名:专业年级:(一)实验目的设计编写首次适应算法实现内存分配,每次从低位开始对内存进行检验分配。

(二)设计思想程序分配内存时每次从最低位开始检验是否有满足分配条件的空闲空间,有则把该进程分配到链表的最后(若在中间有足够空闲空间且与两者差大于最小分配的空间大小则分配到该空闲空间的后面,然后把原空闲空间减去已分配的大小);每次释放空间先检查所释放空间前后是否有空闲空间,有则将空间合并。

(三)主要数据结构及变量说明空间链表数据类型space:struct space{struct space *former; int address;int num; int size; int state; struct space *next;},记录内存空间相关属性;最小分配空间int size_min=10;定义空间链表为S:typedef struct space S;S的指针mem:S *mem;;数据类型struct space *former:链表头结点;数据类型struct space *next:链表尾节点;m存放系统内存空间总大小的值。

(四)流程图(五)运行结果(六)附录(代码):#include<stdio.h>#include<stdlib.h>#include <iostream.h>struct space{struct space *former;int address;int num;int size;int state;struct space *next;};typedef struct space S;S *mem;int size_min=10;int m;void init(){mem=new S;mem->size=m;mem->former=0;mem->next=0;}void alloc(S *ptr,S *assign){if(ptr->next==NULL){if(ptr->size>=assign->size){ptr->size=ptr->size-assign->size;assign->state=1;ptr->next=assign;assign->former=ptr;}else{printf("没有足够的内存空间为进程%d分配\n",assign->num);delete assign;}}else{S *previous,*current;previous=ptr;current=previous->next;while(current!=NULL){if(current->size>=assign->size&&current->state==0){break;}previous=current;current=current->next;}if(current==NULL){if(ptr->size>=assign->size){assign->address =m-(ptr->size);ptr->size=ptr->size-assign->size;assign->state=1;assign->former=previous;previous->next=assign;}else{printf("没有足够的内存空间为进程%d分配\n",assign->num);}}else{if((current->size-assign->size)<=size_min){current->num=assign->num;current->state=1;delete assign;}else{current->size=current->size-assign->size;assign->state=1;assign->address=current->address;current->address=assign->address+assign->size;current->former=assign;assign->next=current;assign->former=previous;previous->next=assign;}}}}void printgroup(S *ptr){S *temp;temp=ptr->next;printf("内存链的状态为:\n");while(temp!=NULL){if(temp->state==0){printf(" 起始地址为:%d",temp->address);printf(" 空闲空间大小为:%d",temp->size);printf(" 内存空闲\n");}else{printf("运行的进程:%d",temp->num);printf(" 起始地址为:%d",temp->address);printf(" 分配空间大小为:%d",temp->size);printf(" 内存已分配\n");}temp=temp->next;}}void free(S *ptr,int i){S *previous,*current;previous=ptr; current=previous->next;while(current!=NULL){if(current->state==1&&current->num==i){break;}previous=current;current=current->next;}if(current==NULL){printf("内存中没有任何进程!!!\n");}else if(current->next==NULL){if(previous->state==0){previous->size=previous->size+current->size;previous->next=NULL;}else{current->state=0;}printf("进程%d释放%d的空间\n",current->num,current->size);printgroup(mem);}else{if(previous->state==0&&(current->next)->state==0){previous->size=previous->size+current->size+(current->next)->s ize;if((current->next)->next==NULL){previous->next=NULL;}else{((current->next)->next)->former=previous;previous->next=(current->next)->next;}}else if(previous->state==0){previous->size=previous->size+current->size;(current->next)->former=previous;previous->next=current->next;}else if((current->next)->state==0){current->size=current->size+(current->next)->size;current->state=0;if((current->next)->next==NULL){previous->next=NULL;}else{((current->next)->next)->former=current;current->next=(current->next)->next;}}else{current->state=0;}printf("进程%d释放%d的空间\n",current->num,current->size);printgroup(mem);}}void Creat(int i,int temp){printf("输入进程名和大小:\n");scanf("%d",&i);scanf("%d",&temp);space *fenpei;fenpei=(S *)malloc(sizeof(space));fenpei->former=NULL;fenpei->address=0;fenpei->size=temp;fenpei->num=i;fenpei->state=0;fenpei->next=NULL;alloc(mem,fenpei);printgroup(mem);}void main(void){int i;int j,k;printf("请输入内存大小:");scanf("%d",&m);init();while(1){printf("**************************\n");printf("申请内存输入数字1\n");printf("释放内存输入数字2\n");printf("中止进程输入数字0\n");printf("**************************\n");scanf("%d",&i);if(i==1){Creat(j,k);}if(i==2){printf("输入进程名:\n");scanf("%d",&j);free(mem,j);}if(i==0){break;}}}。

计算机操作系统实验课实验报告

计算机操作系统实验课实验报告

计算机操作系统实验课实验报告一、实验目的本次计算机操作系统实验课的主要目的是通过实际操作和观察,深入理解计算机操作系统的基本原理和功能,提高对操作系统的实际运用能力和问题解决能力。

二、实验环境本次实验使用的计算机配置为:处理器_____,内存_____,操作系统为_____。

实验所使用的软件工具包括_____。

三、实验内容及步骤(一)进程管理实验1、编写程序创建多个进程,并观察进程的执行顺序和资源分配情况。

首先,使用编程语言(如 C 或 Java)编写代码,创建多个进程。

然后,通过操作系统提供的工具(如任务管理器)观察进程的创建、执行和结束过程。

记录不同进程的执行时间、CPU 使用率和内存占用情况。

2、实现进程间的通信机制,如管道、消息队列等。

分别编写使用管道和消息队列进行进程间通信的程序。

在程序中发送和接收数据,并观察通信的效果和数据的完整性。

(二)内存管理实验1、模拟内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法。

编写程序实现上述三种内存分配算法。

输入不同的内存请求序列,观察每种算法下内存的分配情况和碎片产生情况。

2、研究虚拟内存的工作原理,并进行相关实验。

通过操作系统的设置,调整虚拟内存的大小。

运行大型程序,观察虚拟内存的使用情况和系统性能的变化。

(三)文件系统实验1、实现文件的创建、读写和删除操作。

使用编程语言创建文件,并向文件中写入数据。

读取文件中的内容,并进行验证。

删除文件,观察文件系统的变化。

2、研究文件系统的目录结构和文件权限管理。

观察文件系统的目录层次结构,了解目录的组织方式。

设置文件的权限,如只读、读写、执行等,观察不同权限对文件操作的影响。

四、实验结果与分析(一)进程管理实验结果与分析1、在创建多个进程的实验中,发现进程的执行顺序并非完全按照创建的顺序,而是由操作系统的调度算法决定。

某些进程可能会因为等待资源而暂时被挂起,而其他进程则会得到执行机会。

2、通过进程间通信实验,发现管道通信方式简单直接,但只能用于具有亲缘关系的进程之间;消息队列则更加灵活,可以在不同的进程之间传递消息,但需要更多的编程和管理工作。

内存的分配与回收实验报告(最先适应法)

内存的分配与回收实验报告(最先适应法)

代码实现如下:#include <stdio.h>#include <malloc.h>#include <stdlib.h>#define n 64 //定义内存的大小int a[n],count=0;//数组a用来保存内存使用状况1为已分配0为未分配,count用来记name数组中元素个数char name[n];//已分配内存的名称(字符类型)typedef struct linknode{char pid;int start;int length;struct linknode *left,*right;}de_node; //进程节点结构体定义//head1表示未分配内存队列头指针,head2便是已分配进程队列头指针de_node *head1,*head2=NULL;struct linknode* creat()//创建一个进程节点{int len,flag1=1;//用于表示进程是否可以创建char id;struct linknode* p;p = (de_node *)malloc(sizeof(de_node));//试图在系统内存中开辟空间创建一个进程if (p==NULL) //p为空,说明系统没有可用内存用于创建此模拟进程{ printf("系统没有足够的内存可供使用!\n");//输出return(NULL);//返回空指针}printf("请输入进程id(字符类型)和长度:");//为进程输入id和分配的长度scanf("%c %d",&id,&len);fflush(stdin);//清除输入缓存if((id>='a'&&id<='z'||id>='A'&&id<='Z')&&(len>0)){for(int i=0;i<count;i++)//判断输入的进程名,如果已使用,返回空指针,并释放p指针if(name[i]==id){printf("此名称进程已存在!!");flag1=0;//标志位为0,表示下面对p指向内容不做修改free(p);return NULL;}if(len==0) {//如果输入要分配的进程长度为0,释放p,返回空指针printf("输入长度为0!\n");free(p);return(NULL);}if(flag1){//标志位1,可以对p指向内容进行修改p->pid=id; //idp->start=0; //初始开始内存位置,在以后会修改p->length=len;//长度p->left=NULL;//左指针p->right=NULL;//右指针name[count++]=id;//将id存入数组,count自加return(p);}//返回创建的进程的地址}else {printf("输入进程格式有误\n");free(p);return (NULL);}}//分配内存空间void distribute(de_node *p){ de_node *q=head1,*temp;int flag=0;do{//do_while循法//判断当前指向的内存空间的长度是否满足p所申请的长度,大于就分配if(q->length>=p->length) {p->start=q->start;//把进程的内存开始地址指向内存的可用开始地址处q->start+=p->length;//可用地址起始改变q->length-=p->length;//可用内存长度修改for(int i=p->start;i<p->start+p->length;i++)//将已分配的内存空间全部置1 a[i]=1;flag=1;//表示内存可分配//队列不止一个进程,第一个满足条件,并且刚好分配完,修改指针指向if(q->length==0&&q->right!=q) { if(q==head1)//如果第一个满足,修改头指针指向head1=q->right;q->left->right=q->right;q->right->left=q->left;free(q);//把这个已分配完的空间指针释放}}if(flag==1)//已做完处理直接跳出循环break;if(flag==0)//当前指向的内存不满足,指向下一个,继续判断是否满足q=q->right;}while(q!=head1);//搜索一遍可用内存序列if(flag==0){//没有可用的内存printf("没有满足的内存!\n");count--;//由于创建时加1,但在分配内存时失败,把1又减掉free(p);//把这个未分配到内存的进程释放}if(flag==1){//表示上面已分配好内存,并已修改内存链表,下面修改已分配内存的进程队列temp=head2;//把已分配内存的进程队列赋值给临时指针if(temp==NULL)//如果还还没有存在的任何的进程,说明当前是第一个{ head2=p;//让头指针指向第一个进程p->left=p;//双向队列第一个左右指针都指向自己p->right=p;//双向队列第一个左右指针都指向自己}else if(temp!=NULL){//已存在队列,把当前直接链到第一个,与上面的区别是指针指向head2=p;//让头指针指向p指向的进程p->left=temp->left;//p进程左边为原来第一个的左边p->right=temp;//p进程右边指向第一个temp->left->right=p;//原来第一个的左边为ptemp->left=p;//原来第一个的左边的进程为p}}}//对进程的回收void reclaim(){ char id;int flag=0;de_node *q=head2,*p=head1;if(head2==NULL)//表示当前没有进程{ printf("已没有进程!\n");}else {//已分配内存队列如果不为空printf("输入要回收的进程id:");//输入要回收进程的idscanf("%c",&id);fflush(stdin);for(int i=0;i<count;i++)//双重循环把要回收的进程找出来,并把记录的id去掉if(name[i]==id){//判断当前的进程是否满足要求for(int j=i;j<count;j++)name[j]=name[j+1];//向前覆盖name[j+1]=NULL;//置空count--;//减一}//判断是否总共只有一个进程且是够刚好也满足条件if(q->pid==id&&q->right==q&&head2==q){ head2=NULL;//把已分配队列直接置空flag=1;//表示找到满足条件的进程}if(flag==0){//上面的都没找到do{if(q->pid==id){//如果找到if(q==head2)head2=q->right;q->left->right=q->right;//修改指针指向q->right->left=q->left;flag=1;break;}else q=q->right;}while(q!=head2);}//如果找到或是遍历一遍结束if(flag==0) printf("没有此进程号!!!\n");//没有找到满足的进程if(flag==1){//表示找到了for(int i=q->start;i<q->start+q->length;i++)//释放占有的内存a[i]=0;//接下来修改可用内存的队列,while(q->start>p->start&&p->right!=head1){//从第一个开始找到回收回来的内存开始地址大的那个队列p=p->right;}if(p==head1)//表示比第一个的开始还小,那么就要修改头地址head1=q;//其他情况不用修改头地址,只需找到应该的位置,把此进程插进去q->left=p->left;//修改指针的指向q->right=p;p->left->right=q;p->left=q;if(q->start+q->length==p->start)//可以与后面合并的情况{ q->length+=p->length;//修改指针的指向p->right->left=q;q->right=p->right;free(p);}if(q->left->start+q->left->length==q->start)//可以与前面合并的情况{ q->left->length+=q->length;//修改指针的指向q->left->right=q->right;q->right->left=q->left;free(q);}}}}//打印输出void print(){ de_node *q=head2,*p=head1;if(count==0)printf("没有进程占有内存。

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

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

第1篇一、实验目的本次实验旨在让学生深入理解内存分配的基本原理和不同分配算法,通过实际操作,提高学生对内存管理技术的掌握程度。

通过本次实验,我们希望达到以下目标:1. 熟悉内存分配的基本概念和过程;2. 掌握常见的内存分配算法,如首次适应算法、最佳适应算法和最坏适应算法;3. 理解内存分配中的碎片问题,并尝试解决;4. 培养学生的动手实践能力和问题解决能力。

二、实验内容1. 实验环境:使用C语言编写程序,运行在Linux操作系统上。

2. 实验步骤:(1)首次适应算法:从内存空间的起始位置开始查找,找到第一个满足申请大小的空闲分区,将其分配给请求者。

(2)最佳适应算法:从所有空闲分区中查找一个最小的满足申请大小的分区,将其分配给请求者。

(3)最坏适应算法:从所有空闲分区中查找一个最大的满足申请大小的分区,将其分配给请求者。

(4)解决内存碎片问题:采用紧凑算法,将所有空闲分区合并成一个连续的大空间,从而减少内存碎片。

三、实验过程1. 编写程序实现内存分配算法,包括内存初始化、申请内存、释放内存等功能。

2. 对不同分配算法进行测试,观察分配效果,分析不同算法的优缺点。

3. 分析内存碎片问题,尝试解决方法,如紧凑算法。

四、实验结果与分析1. 首次适应算法:该算法简单易实现,但可能导致内存利用率较低,且可能产生较大的内存碎片。

2. 最佳适应算法:该算法分配效果较好,内存利用率较高,但分配速度较慢。

3. 最坏适应算法:该算法分配效果较差,内存利用率较低,但分配速度较快。

4. 紧凑算法:通过合并空闲分区,减少了内存碎片,提高了内存利用率。

五、实验体会1. 通过本次实验,我们深入了解了内存分配的基本原理和不同分配算法,掌握了常见内存分配算法的优缺点。

2. 实验过程中,我们遇到了各种问题,如内存碎片问题、算法实现问题等,通过查阅资料、讨论和尝试,最终解决了这些问题,提高了我们的问题解决能力。

3. 实验使我们认识到,内存管理是操作系统中的一个重要组成部分,对计算机性能和稳定性有着重要影响。

操作系统实验-存储分配报告

操作系统实验-存储分配报告

存储管理-动态不等长存储资源分配算法报告人: 0609一、实验目的理解动态异长存储分区资源管理,掌握所需数据结构和管理程序,了解各种存储分配算法的优点和缺点,充分掌握FF、BF、WF算法二、实验内容(1) 分析UNIX最先适应(FF)存储分配算法,即map数据结构、存储分配函数malloc()和存储释放函数mfree(),找出与算法有关的成分。

(2) 修改上述与算法有关的成分,使其分别体现BF分配原则和WF分配原则。

三、实验内容、方法(1)设计结构体模拟物理内存块(2)分别模拟FF、BF、WF三种适应算法动态地创建进程(3)能够动态地销毁进程并更新可用表与已分配表(4)显示出各个时间段内存块中已分配表与可用表的情况四、实验设计及思想(1) 按内容要求编写最佳适应和最坏适应存储分配算法。

(2) 编写测试程序,对存储分配表进行初始化。

然后对用户输入的请求和释放,按算法动态更新存储分配表,并将每次更新之后的存储分配表在屏幕上显示出来。

(3)动态分区的分配与回收主要解决3个问题:A 、对于请求表中的要求内存长度,从可用表或自由链寻找出合适的空闲区分配程序B 、分配空闲区之后,更新可用表或自由链C 、进程或作业释放内存资源时,合并相邻空闲区并刷新可用表动态分区时的分配方法有最先适应法(FF )、最佳适应法(BF )及最坏适应法(WF )三种:FF 适应法要求可用表按起始地址递增次序排列,一旦找到大于或等于要求内存长度的可用块时立即分配;BF 适应算法要求从小到大的次序组成可用表,每次分配可用表中长度与要求分配的内存块最接近的内存块;WF 适应法要求可用表按长度大小递减排列,每次分配可用表中长度最大的内存块。

五、设计流程图主要流程:图1 主流程BF 适应法流程图:图2 BF 适应法流程图 WF 适应法流程图:图3 WF适应法流程图六、实验结果。

操作系统-内存分配与回收模拟-实验06

操作系统-内存分配与回收模拟-实验06

操作系统课程实验报告
(1)首次适应算法实现
从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。

为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。

该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。

(2)最佳适应算法实现
它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。

为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。

数据结构体分析
(3)内存回收
将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。

并判断该空闲块是否与其他空闲块相连,若释放的内存空间与空闲块相连时,则合并为同一个空闲块,同时修改分区大小及起始地址。

首次适配算法流程图:
最佳适配算法流程图:
内存回收:
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#define M 20
#define N 101
#define max_size 128
int i = 0,choose;
int id= 0,size = 0,countOfEmpty = 1,countOfNotEmpty = 0,num = 1;。

操作系统实验内存分配

操作系统实验内存分配

实验四存储器管理一、实验名称:存储器管理二、实验目的在TC、VB、Delphi、C++Builder等语言与开发环境中,模拟操作系统的内存管理;通过程序运行所显示的内存使用的各项指标,加深对内存管理的理解。

三、实验内容实现主存储器空间的分配和回收。

本实验有两个题,学生可选择其中的一题做实验。

第一题:在固定分区管理方式下实现主存分配和回收。

第二题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。

[提示]:可变分区方式是按作业需要的主存空间大小来分割分区的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。

随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。

为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:起址长度状态第一栏14 K 12 K 未分配第二栏32 K 96 K 未分配空表目空表目其中,起址——指出一个空闲区的主存起始地址。

长度——指出从起始地址开始的一个连续空闲的长度。

状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白(无效),可用来登记新的空闲区(例如,作业撤离后,它所占的区域就成了空闲区,应找一个“空表目”栏登记归还区的起址和长度且修改状态)。

由于分区的个数不定,所以空闲区说明表中应有适量的状态为“空表目”的登记栏目,否则造成表格“溢出”无法登记。

空闲区表的定义为:#define m 10 /*假定系统允许的空闲区表最大为m*/struct{ float address; /*起始地址*/float length; /*长度*/int flag; /*标志,用“0”表示空栏目,用“1”表示未分配*/ }free_table[m]; /*空闲区表*/上述的这张说明表的登记情况是按提示(1)中的例所装入的三个作业占用的主存区域后填写的。

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

操作系统实验之内存管理实验报告
//空闲分区 typedef struct Free_Block {
int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block;
定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情
该模块完成在内存空间中申请一块空间供进程使用的功能,通过输入进程大 小系统先查看内存空间中是否有足够的空间供其进行申请,若无,显示分配失败 相应信息,否则在空闲内存分区块中选择最先的一块进行分配,若内存空间不足 则继续向下查找,空闲内存分区的顺序通过三种算法给出。分配内存时,要指定 进程的首地址和大小,并对内存空闲分区的大小做相应的修改。 2.4 进程终止模块
四、开发工具及主要源代码
1、开发工具
sublimeText3 文本编辑器,采用 g++编译。
2、主要源码
这里只给出最先适应算法的源码,由于三种算法均为对链表进行排序,只是 排序依据的属性不同,结构上几乎相似,在此就不做赘述 /*最先适应算法,按地址的大小由小到达排序*/
void rFirst_Fit() {
current_min_addr = temp->next->start_addr; p = temp; } temp = temp->next; } if (p->next != head->next) { temp = p->next; p->next = p->next->next; temp->next = head->next;
不足之处在于,本次实验中没有实现最坏适应法,分析可能是在在排序的 过程中链表的指针出现了错误,在开始调试阶段只对单一算法进行了调试从而 忽略了这个问题的存在,直到编写本报告的时候才发现种问题。

计算机操作系统内存分配实验报告

计算机操作系统内存分配实验报告

一、实验目的熟悉主存的分配与回收。

理解在不同的存储管理方式下.如何实现主存空间的分配与回收。

掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。

所谓分配.就是解决多道作业或多进程如何共享主存空间的问题。

所谓回收.就是当作业运行完成时将作业或进程所占的主存空间归还给系统。

可变分区管理是指在处理作业过程中建立分区.使分区大小正好适合作业的需求.并且分区个数是可以调整的。

当要装入一个作业时.根据作业需要的主存量查看是否有足够的空闲空间.若有.则按需要量分割一个分区分配给该作业;若无.则作业不能装入.作业等待。

随着作业的装入、完成.主存空间被分成许多大大小小的分区.有的分区被作业占用.而有的分区是空闲的。

实验要求使用可变分区存储管理方式.分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行.分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。

同时.要求设计一个实用友好的用户界面.并显示分配与回收的过程。

同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。

三、实验主要仪器设备和材料实验环境硬件环境:PC或兼容机软件环境:VC++四、实验原理及设计分析某系统采用可变分区存储管理.在系统运行当然开始.假设初始状态下.可用的内存空间为640KB.存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。

(作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放60KB 、作业4 申请200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB)当作业1进入内存后.分给作业1(130KB).随着作业1、2、3的进入.分别分配60KB、100KB.经过一段时间的运行后.作业2运行完毕.释放所占内存。

内存分配实验报告

内存分配实验报告

1. 理解内存分配的基本原理和方法;2. 掌握常见内存分配算法的实现过程;3. 分析不同内存分配算法的性能特点;4. 通过实验加深对内存管理机制的理解。

二、实验环境1. 操作系统:Windows 102. 编程语言:C语言3. 开发环境:Visual Studio 2019三、实验内容1. 内存分配算法本次实验主要实现了以下几种内存分配算法:(1)首次适应算法(First Fit):从空闲分区列表的头部开始查找,找到第一个足够大的分区进行分配。

(2)最佳适应算法(Best Fit):在所有空闲分区中,找到与请求大小最接近的分区进行分配。

(3)最坏适应算法(Worst Fit):在所有空闲分区中,找到最大的分区进行分配。

2. 内存分配过程实验中,我们模拟了一个简单的内存分配过程,包括以下步骤:(1)初始化内存:创建一个足够大的内存空间,并初始化为空闲状态。

(2)请求内存:模拟用户对内存的需求,以随机方式生成请求大小。

(3)内存分配:根据请求大小,选择合适的内存分配算法进行分配。

(4)内存回收:模拟用户释放内存的过程,将释放的内存空间重新标记为空闲状态。

1. 定义内存空间:创建一个足够大的数组来模拟内存空间。

2. 定义空闲分区链表:使用链表结构存储空闲分区信息,包括分区大小、起始地址等。

3. 实现内存分配算法:(1)首次适应算法:遍历空闲分区链表,找到第一个足够大的分区进行分配。

(2)最佳适应算法:遍历空闲分区链表,找到与请求大小最接近的分区进行分配。

(3)最坏适应算法:遍历空闲分区链表,找到最大的分区进行分配。

4. 实现内存回收功能:将释放的内存空间重新标记为空闲状态。

5. 测试内存分配算法:生成一系列随机请求大小,测试不同内存分配算法的性能。

五、实验结果与分析1. 首次适应算法:在请求内存时,算法效率较高,但可能会产生较多的外部碎片。

2. 最佳适应算法:在请求内存时,算法效率较低,但分配的内存空间利用率较高,外部碎片较少。

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

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

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

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

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

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

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

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

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

装入作业的时候首先初始化一个链表,根据用户输入的操作代号进行相应的操作。

若用户选择装入作业首先判断空闲分区表里有没有比作业需要的内存大的分区,若有直接分配,若没有进行紧凑操作,再将紧凑后的空闲分区与作业大小比较,若能装的下则分配给作业,若是进行紧凑后的空闲分区仍不能装入整个作业则通知用户内存不够。

2、流程图2、代码实现#include<stdio.h>#include<stdlib.h>#include<time.h>#include<windows.h>#define TURE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define SIZE 3//进程表int ppNo=1; //用于递增生成进程号int pLength=0;struct PCB{int pNo; //进程号(名)int pSize; // 进程大小int pOccupy; // 实际占用的内存int pStartAddr; // 进程起始地址int pState; //进程状态};struct PCB pList[200];//////////////////空闲分区表部分/////////////////////////////////////////////////////typedef int Status;typedef struct emptyNode{ //空闲分区结构体int areaSize; //空闲分区大小int aStartAddr; //空闲分区始址struct emptyNode *next;}emptyNode,*LinkList;int ListDelete(struct PCB *pList,int i);//删除下标为i的进程void pSort(struct PCB *pList); //内存中的进程按始址递增排序void compact(LinkList &L,struct PCB *pList);//紧凑,内存中进程移动,修改进程数据结构;空闲分区合并,修改空闲分区表数据结构void amalgamate(LinkList &L); //回收后进行合并空闲分区void recycle(LinkList &L,struct PCB *pList); //回收,从进程表中删除进程,把释放出的空间插入到空闲分区链表中Status InitList(LinkList &L); ///构造一个新的有头节点的空链表L Status ClearList(LinkList &L); ///将链表L重置为空表Status ListInsert(LinkList &L,LinkList s1); //根据始址进行插入void DeleteElem(LinkList &L,int aStartAddr);//删除线性表中始址值为aStartAddr的结点void PrintList(LinkList L); //输出各结点的值void creatP(struct PCB *p); ///初始化进程int search(LinkList &L,int pSize); //检索分区表,返回合适分区的首址int add(LinkList &L); //返回空闲分区总和void pListPrint(struct PCB *pList); //AAA/输出内存中空间占用情况void distribute(LinkList &L,struct PCB *process);int ListDelete(struct PCB *pList,int i)//AAA/删除下标为i的进程{for(;i<pLength-1;i++){pList[i]=pList[i+1];}pLength--;}//ListDeletevoid pSort(struct PCB *pList){ //AAA/内存中的进程按始址递增排序int i,j;struct PCB temp;for(i=0;i<pLength-1;i++){for(j=0;j<pLength-i-1;j++){if(pList[j].pStartAddr>pList[j+1].pStartAddr){temp=pList[j];pList[j]=pList[j+1];pList[j+1]=temp;}}}}void compact(LinkList &L,struct PCB *pList){//AAA/紧凑,内存中进程移动,修改进程数据结构;空闲分区合并,修改空闲分区表数据结构printf("进行紧凑\n");//1、进程移动,修改进程数据结构int i;pList[0].pStartAddr=0; //第一个进程移到最上面for(i=0;i<pLength-1;i++){pList[i+1].pStartAddr=pList[i].pStartAddr+pList[i].pOccupy;}//2、空闲分区合并,修改空闲分区表数据结构LinkList p=L->next,s;int sumEmpty=0;while(p!=NULL)//求空闲区总和{sumEmpty+=p->areaSize;p=p->next;}//printf("清空前\n");//PrintList(L);ClearList(L); //清空空闲分区表//printf("清空后\n");//PrintList(L);s=(LinkList)malloc(sizeof(emptyNode));s->aStartAddr=pList[pLength-1].pStartAddr+pList[pLength-1].pOccupy;s->areaSize=sumEmpty;ListInsert(L,s);//printf("插入后\n");//PrintList(L);// p rintf("\n紧凑后的>>>>\n");pListPrint(pList);PrintList(L);}void amalgamate(LinkList &L){//AAA/回收后进行合并空闲分区LinkList p=L->next,q=p->next;while(q!=NULL){if(p->aStartAddr+p->areaSize==q->aStartAddr){p->areaSize+=q->areaSize;DeleteElem(L,q->aStartAddr);//删除被合并的结点q=p->next;}else{p=q;q=q->next;}}}void recycle(LinkList &L,struct PCB *pList){//AAA/回收,从进程表中删除进程,把释放出的空间插入到空闲分区链表中int index,delPNo,delPSize,delPOccupy,delPStartAddr;LinkList s;//srand(time(0));//index=rand()%pLength;printf("请输入要回收的进程号:");scanf("%d",&index);delPNo=pList[index-1].pNo;delPSize=pList[index-1].pSize;delPOccupy=pList[index-1].pOccupy;delPStartAddr=pList[index-1].pStartAddr;//printf("__________________________________________________________________ ______________");ListDelete(pList,index-1);//pListPrint(pList);s=(LinkList)malloc(sizeof(emptyNode));s->areaSize=delPOccupy;s->aStartAddr=delPStartAddr;ListInsert(L,s);amalgamate(L);pListPrint(pList);//输出内存中空间占用情况PrintList(L);/////////////////////////////////////////////////////////////////////////////Status InitList(LinkList &L) //1AAA/构造一个新的有头节点的空链表L {LinkList s;L=(LinkList)malloc(sizeof(emptyNode)); //生成新节点(头结点)if(!L) return ERROR; //申请内存失败s=(LinkList)malloc(sizeof(emptyNode));s->areaSize=100;s->aStartAddr=0;L->next=s; //头节点的指针域指向第一个结点s->next=NULL;return OK;}//InitListStatus ClearList(LinkList &L) //2AAA/将链表L重置为空表{LinkList p,r;p=L->next; r=p->next;while(p!=NULL){free(p);if(r==NULL){p=NULL;}else{p=r;r=p->next;}}L->next=NULL;return OK;}//ClearListStatus ListInsert(LinkList &L,LinkList s1) //AAA/*****根据始址进行插入{LinkList r=L,p=L->next,s;//指针s=(LinkList)malloc(sizeof(emptyNode));s->areaSize=s1->areaSize;s->aStartAddr=s1->aStartAddr;if(p==NULL){L->next=s;s->next=NULL;}else{while(p!=NULL){if(s1->aStartAddr < p->aStartAddr){s->next=r->next;r->next=s;break;}r=p;p=p->next; //后移}if(p==NULL){r->next=s;s->next=NULL;}}return OK;}//ListInsert2void DeleteElem(LinkList &L,int aStartAddr)//*****删除线性表中始址值为aStartAddr 的结点{LinkList p=L,q;while(p->next!=NULL){q=p->next;if(q->aStartAddr==aStartAddr){p->next=q->next;free(q);}elsep=p->next;}}//DeleteElem///////////////////////////////////////////////////////////////////////////////void PrintList(LinkList L)//AAA/*****输出各结点的值{LinkList p=L->next;while(p!=NULL){printf(" %d \t\t\t%d KB\n",p->aStartAddr,p->areaSize);p=p->next;}printf("\n");}//PrintListvoid creatP(struct PCB *p){ //AAA/初始化进程int size;//srand(time(NULL));//size=rand()%7+1;printf("请输入进程大小:");scanf("%d",&size);//size=10;p->pNo=ppNo++;p->pSize=size;p->pOccupy=0;p->pStartAddr=0;p->pState=0;}int search(LinkList &L,int pSize){ //AAA/检索分区表,返回合适分区的首址LinkList p=L->next;while(p!=NULL){if(p->areaSize>=pSize){////成功printf("search分区%d %d\n",p->areaSize,pSize);return p->aStartAddr;}p=p->next;}return -1;//没有足够大的}int add(LinkList &L){ //AAA/返回空闲分区总和LinkList p=L->next;int sum=0;while(p!=NULL){sum+=p->areaSize;p=p->next;}return sum;}void pListPrint(struct PCB *pList){//AAA/输出内存中空间占用情况printf("\n进程分配情况: 起始地址\t\t大小\t\t进程号\n");for(int i=0;i<pLength;i++){printf(" %d\t\t\t %d K\t\t%d\n",pList[i].pStartAddr,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 < %d KB",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",p.pNo,p.pSize);//1、请求分配size//2、检索空闲分区表(首次适应FF)//PrintList(L);stAddr=search(L,p.pSize);//得到足够大的分区的始址,没有则返回-1if(stAddr==-1){//没有足够大的分区if(add(L)>=p.pSize){//空闲区总和足够大// 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的内存。

内存分配实验报告

内存分配实验报告

内存分配实验报告内存分配实验报告一、引言内存分配是计算机科学中一个重要的概念,它涉及到操作系统、编程语言以及计算机硬件等多个方面。

在本次实验中,我们将探索不同的内存分配算法,并对它们的性能进行评估和比较。

二、实验目的1. 理解内存分配的基本原理和概念;2. 学习不同的内存分配算法,并掌握它们的优缺点;3. 通过实验对比,评估不同算法在不同场景下的性能表现。

三、实验方法1. 实验环境本次实验使用C语言编写,运行在Linux操作系统上。

实验中使用了常见的内存分配算法,包括首次适应算法、最佳适应算法和最坏适应算法。

2. 实验步骤(1)首次适应算法首次适应算法是一种简单而常用的内存分配算法。

它从内存的起始位置开始查找,找到第一个能满足分配要求的空闲块进行分配。

实验中,我们模拟了一系列内存分配请求,并记录了每次分配的时间和分配结果。

(2)最佳适应算法最佳适应算法是一种在空闲块中选择最小合适空间进行分配的算法。

实验中,我们使用了一个链表来维护空闲块,并按照大小进行排序。

每次分配请求时,选择最小合适的空间进行分配,并更新链表。

同样,我们记录了每次分配的时间和分配结果。

(3)最坏适应算法最坏适应算法与最佳适应算法相反,它选择最大合适空间进行分配。

实验中,我们同样使用链表维护空闲块,并按照大小进行排序。

每次分配请求时,选择最大合适的空间进行分配,并更新链表。

同样,我们记录了每次分配的时间和分配结果。

四、实验结果与分析通过实验,我们得到了不同内存分配算法在不同场景下的性能表现。

首次适应算法在处理大量小内存请求时表现较好,因为它能够更快地找到合适的空闲块。

而最佳适应算法在处理大量大内存请求时表现较好,因为它能够更好地利用内存空间。

最坏适应算法则在处理大量随机大小的内存请求时表现较好,因为它能够更快地找到较大的空闲块。

五、实验总结通过本次实验,我们深入了解了内存分配算法的原理和应用。

不同的算法适用于不同的场景,我们需要根据实际需求选择合适的算法。

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

计算机操作系统内存分配实验报告记录————————————————————————————————作者:————————————————————————————————日期:一、实验目的熟悉主存的分配与回收。

理解在不同的存储管理方式下,如何实现主存空间的分配与回收。

掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。

所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。

所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。

可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。

随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。

实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。

同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。

同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。

三、实验主要仪器设备和材料实验环境硬件环境:PC或兼容机软件环境:VC++ 6.0四、实验原理及设计分析某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。

(作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB)当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。

此时,作业4进入系统,要求分配200KB内存。

作业3、1运行完毕,释放所占内存。

此时又有作业5申请140KB,作业6申请60KB,作业7申请50KB。

为它们进行主存分配和回收。

1、采用可变分区存储管理,使用空闲分区链实现主存分配和回收。

空闲分区链:使用链指针把所有的空闲分区链成一条链,为了实现对空闲分区的分配和链接,在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针,由状态位指示该分区是否分配出去了;同时,在分区尾部还设置有一后向指针,用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间,当该分区分配出去后,状态位就由“0”置为“1”。

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

设计一个空闲分区说明链,设计一个某时刻主存空间占用情况表,作为主存当前使用基础。

初始化空间区和已分配区说明链的值,设计作业申请队列以及作业完成后释放顺序,实现主存的分配和回收。

要求每次分配和回收后显示出空闲内存分区链的情况。

把空闲区说明链的变化情况以及各作业的申请、释放情况显示打印出来。

2.采用可变分区存储管理,分别采用首次适应算法、最佳适应算法和最坏适应算法实现主存分配和回收。

3、主存空间分配(1)首次适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足要求的空闲区,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

(2)最佳适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中(3)最坏适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

4、主存空间回收当一个作业执行完成撤离时,作业所占的分区应该归还给系统。

归还的分区如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明链中,此时,相邻空闲区的合并问题,要求考虑四种情况:(1)释放区下邻空闲区(低地址邻接)(2)释放区上邻空闲区(高地址邻接)(3)释放区上下都与空闲区邻接(4)释放区上下邻都与空闲区不邻接五、程序流程图main函数里的流程图选择a=1,首次a=2,最佳a=3,最坏初始化整理分显示空闲选择操i=1,分配i=0,退i=2,回收结分配空间里的流程图回收空间里的流程图p->data.l分配分配空a=a=a=输入申按顺序初始化q ,输入申初始化q ,p->data.l p 的状态剩下 p->data.le 输入申Y Y N N 返回到整理六、相关数据结构及关键函数说明本程序采用了一个struct free_table 数据结构,里面包含分区序号(num )、起始地址(address )、分区长度(length )和分区状态(state )。

还用了线性表的双性链表存储结构(struct Node ),里面包含前区指针(prior )和后继指针(next )。

一开始定义一条(含有first 和end )的链,用开始指针和尾指针开创空间链表。

然后分别按三种算法进行分配和回收。

p 的回收p ,p 的前一个为p 的后一个是endp 的后一个状态空与后面空闲块相连将p 的状态改为空闲将p 的状态改为空闲回收空p 的后一个是endYNYNYNp 的前一个状态空p 的前一个状态空p 的后一个状态空p 的后一个状态空p 的后一个状态空p 的后一个状态空YYYNNN与前面空闲块相连p 的与前面空闲块相连与后面空闲块相连YN 返回到整理在该程序中关键函数有,sort()、allocation()、recovery()、和First_fit()、Best_fit ()、Worst_fit();其中sort()函数是用来整理分区序号的,如在删序号3时,她与前面序号2相连在一起了,然后序号2中的长度总满足申请的内存大小,就会在序号2中分配,然后序号在2的基础上加1,一直加,加到与原本序号3的下一个序号也就是4相等,这时sort()就开始有明显的工作了;allocation()是分配空间的,也是过渡到三个算法中的,当三个算法中满足或者不满足分配请求,都会又返回值给allocation();recovery()是用来回收内存的,里面包含了四种情况相连结果,即释放区上与空闲区邻接、释放区下与空闲区邻接、释放区上下都与空闲区邻接、释放区上下都与空闲区不邻接这四种情况的结果。

七、源代码#include<stdio.h>#include<stdlib.h>#define OK 1 //完成#define ERROR 0 //出错typedef int Status;typedef struct free_table//定义一个空闲区说明表结构{int num; //分区序号long address; //起始地址long length; //分区大小int state; //分区状态}ElemType;typedef struct Node// 线性表的双向链表存储结构{ElemType data;struct Node *prior; //前趋指针struct Node *next; //后继指针}Node,*LinkList;LinkList first; //头结点LinkList end; //尾结点int flag;//记录要删除的分区序号Status Initblock()//开创带头结点的内存空间链表{first=(LinkList)malloc(sizeof(Node));end=(LinkList)malloc(sizeof(Node));first->prior=NULL;first->next=end;end->prior=first;end->next=NULL;end->data.num=1;end->data.address=40;end->data.length=600;end->data.state=0;return OK;}void sort()//分区序号重新排序{Node *p=first->next,*q;q=p->next;for(;p!=NULL;p=p->next){for(q=p->next;q;q=q->next){if(p->data.num>=q->data.num){q->data.num+=1;}}}}//显示主存分配情况void show(){ int flag=0;//用来记录分区序号Node *p=first;p->data.num=0;p->data.address=0;p->data.length=40;p->data.state=1;sort();printf("\n\t\t》主存空间分配情况《\n");printf("**********************************************************\n\n");printf("分区序号\t起始地址\t分区大小\t分区状态\n\n");while(p){printf("%d\t\t%d\t\t%d",p->data.num,p->data.address,p->data.length);if(p->data.state==0) printf("\t\t空闲\n\n");else printf("\t\t已分配\n\n");p=p->next;}printf("**********************************************************\n\n"); }//首次适应算法Status First_fit(int request){//为申请作业开辟新空间且初始化Node *p=first->next;LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p){if((p->data.state==0)&&(p->data.length==request)){//有大小恰好合适的空闲块p->data.state=1;return OK;break;}else if((p->data.state==0) && (p->data.length>request)){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;temp->data.num=p->data.num;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.length;p->data.length-=request;p->data.num+=1;return OK;break;}p=p->next;}return ERROR;}//最佳适应算法Status Best_fit(int request){int ch; //记录最小剩余空间Node *p=first;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最小空间和最佳位置{if((p->data.state==0) && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length > p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.state=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//最差适应算法Status Worst_fit(int request){int ch; //记录最大剩余空间Node *p=first->next;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最大空间和最佳位置{if(p->data.state==0 && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length < p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.length=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//分配主存Status allocation(int a){int request;//申请内存大小printf("请输入申请分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("分配大小不合适,请重试!");return ERROR;}switch(a){case 1: //默认首次适应算法if(First_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 2: //选择最佳适应算法if(Best_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 3: //选择最差适应算法if(Worst_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;}}Status deal1(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.length+=q->next->data.length;q->next=q->next->next;q->next->next->prior=q;q->data.state=0;q->data.num=flag;}if(q->prior->data.state==0&&q->next->data.state==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}Status deal2(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=p->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.state=0;}if(q->prior->data.state==0&&q->next->data.state==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}//主存回收Status recovery(int flag){Node *p=first;for(;p!=NULL;p=p->next){if(p->data.num==flag){if(p->prior==first){if(p->next!=end)//当前P指向的下一个不是最后一个时{if(p->next->data.state==0) //与后面的空闲块相连{p->data.length+=p->next->data.length;p->next->next->prior=p;p->next=p->next->next;p->data.state=0;p->data.num=flag;}else p->data.state=0;}if(p->next==end)//当前P指向的下一个是最后一个时{p->data.state=0;}}//结束if(p->prior==block_first)的情况else if(p->prior!=first){if(p->next!=end){deal1(p);}else{deal2(p);}}//结束if(p->prior!=block_first)的情况}//结束if(p->data.num==flag)的情况}printf("\t****回收成功****");return OK;}//主函数void main(){int i; //操作选择标记int a;//算法选择标记printf("**********************************************************\n");printf("\t\t用以下三种方法实现主存空间的分配\n");printf("\t(1)首次适应算法\t(2)最佳适应算法\t(3)最差适应算法\n");printf("**********************************************************\n");printf("\n");printf("请输入所使用的内存分配算法:");scanf("%d",&a);while(a<1||a>3){printf("输入错误,请重新输入所使用的内存分配算法:\n");scanf("%d",&a);}switch(a){case 1:printf("\n\t****使用首次适应算法:****\n");break;case 2:printf("\n\t****使用最佳适应算法:****\n");break;case 3:printf("\n\t****使用最坏适应算法:****\n");break;}Initblock(); //开创空间表while(1){show();printf("\t1: 分配内存\t2: 回收内存\t0: 退出\n");printf("请输入您的操作:");scanf("%d",&i);if(i==1)allocation(a); // 分配内存else if(i==2) // 内存回收{printf("请输入您要释放的分区号:");scanf("%d",&flag);recovery(flag);}else if(i==0){printf("\n退出程序\n");break; //退出}else //输入操作有误{printf("输入有误,请重试!");continue;}}}八、执行结果和结果分析初始化首次适应算法:当作业1、2、3顺利分配内存空间后:回收序号2里面的内存:分配作业4:回收序号3里面的内存(与上邻序号2相连了)回收序号1里的内存(与下邻序号2相连了)继续分配(会发现总是按顺序查找满足要求的第一个空闲块,一旦发现就会分配):初始化最佳适应算法:继续分配(会发现总是查找满足要求的空闲块且其比其他空闲块长度小,一旦发现就会分配):初始化最坏适应算法:继续分配(会发现总是查找满足要求的空闲块且其比其他空闲块长度小,一旦发现就会分配):九、所遇困难的解决以及心得体会本实验我采取用一条链表同时表示空闲分区链和主存空间占用情况,因为主存总大小是固定的,把空闲分区链所表示的区域从总的内存里去除就是被占用的空间的大小,这个实验还是比较简单的,但在执行过程中还是遇到了很多问题,如在回收空间的函数中,因为要考虑到四种情况,我一开始的想法是这样的:让p指向链表开头,一直等找到p所指向的分区序号等于要删除的分区序号,然后开始执行,当p->prior不是链首first时要考虑p->next是不是链尾end,然后继续考虑p的前向指针和后向指针得状态是否为空闲;等考虑完p->prior 不是链首了,就进行考虑p->prior是链首的问题,然后又进行了考虑p->next是不是链尾end,然后继续考虑p的前向指针和后向指针得状态是否为空闲;等考虑完了p->prior的问题又进行考虑p->next的问题,一直这样重复了,我都不知道,当时超烦的,后来静下心重新检查自己写得程序,才知道自己写得这个函数好凌乱。

相关文档
最新文档