实验四 主存空间的分配和回收模拟
实验四、主存空间的分配和回收模拟
物联网工程 陈梓帆 201306104108
一、实验目的
为了合理地分配和使用这些存储空间,当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间和使用情况,找出足够的空闲区域给申请者。当作业撤离归还主存资源时,则存储管理要收回占用的主存空间。主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助我们理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
用高级语言完成一个主存空间的分配和回收模拟程序,以加深对内存分配方式及其算法的理解。
二、实验内容和要求
2.1 模拟包括3部分:
1)实现特定的内存分配算法
2)实现内存回收模拟
3)每种内存分配策略对应的碎片数统计
2.2 固定分区存储管理
假设内存容量为120KB,并且分别划分成8,16,32,64KB大小的块各一块。
一个进程所需要的内存为0到100个KB。同时假设一个进程在运行过程中所需内存的大小不变。
模拟五个进程到达请求分配与运行完回收情况,输出主存分配表.
2.3 动态分区分配存储管理
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、下次适应算法、最佳适应算法和最坏适应算法4种算法完成设计(任选两种算法)。
(1)在程序运行过程,由用户指定申请与释放。
(2)设计一个已占用分区表,以保存某时刻主存空间占用情况。
(3)设计一个空闲分区表,以保存某时刻主存空间剩余情况。
(4)用两个表的变化情况,反应各进程所需内存的申请与释放情况。
三、实验方法、步骤及结果测试
1. 源程序名:压缩包文件(rar或zip)中源程序名 zxl4.c
可执行程序名:zxl.exe
2. 原理分析及流程图
①.首先设置一个结构体类型的内存分区,用于存放内存的起始地址、长度、任务名和志向下一个空闲分区的指针;
②.设置showmemory函数,显示当前内存分配情况 ;
③.memoallocate函数,用于分配内存;
④.Minsert函数,功能插入任务到空闲分区;
⑤.memoreturn函数,用于回收内存;Mreturn函数,功能回收内存;
⑥.main函数,用户自行选择,系统做出响应。
3. 主要程序段及其解释:
#include <stdio.h> #include <stdlib.h> #include <string.h> const int CANUSE = 1; const int CANTUSE = 0; //#define MSIZE 128; const int MSIZE = 128; //内存分区 struct MZone { //空闲区起始地址 int begin_addr; //一个连续空闲区的长度 int length; //状态 int state; //内存中任务名 char task_name[32]; //指向下一个空闲分区 struct MZone *next; }; //内存头指针 struct MZone *Mhead = NULL; //showmemory函数,显示当前内存分配情况 void showmemory() { struct MZone *Mpoint = Mhead; printf("内存的使用情况\n"); printf("beginaddr\tlength\tstate\ttask\n"); while( NULL!=Mpoint) { printf("%dk\t\t",Mpoint->begin_addr); printf("%dk\t",Mpoint->length); Mpoint->state?printf("CANUSE\t"):printf("CANTUSE\t"); printf("%s\n",Mpoint->task_name); Mpoint = Mpoint->next; } system("pause"); } //memoallocate函数,用于分配内存 void memoallocate(void) { struct MZone *Mnew = (struct MZone*)malloc(sizeof(struct MZone)); printf("输入要分配内存大小(kb):\n"); scanf("%d",&Mnew->length); printf("输入任务名:\n"); scanf("%s",&Mnew->task_name); Minsert(Mnew)?printf("分配内存成功\n"):printf("没有符合大小的空闲分区,内存分配失败。\n"); system("pause"); free(Mnew); } //Minsert函数,功能插入任务到空闲分区 int Minsert(struct MZone* Mnew) { struct MZone *Zinsert = Mhead; //flag用于指示是Zinsert到了NULL,既没有内存可以分配 int flag = 1; while( Zinsert->length<Mnew->length || !Zinsert->state) { if( NULL!=Zinsert->next ) { Zinsert = Zinsert->next; } else { Zinsert = Zinsert->next; break; } } if( NULL==Zinsert ) { return 0; } if( MSIZE == Zinsert->begin_addr+Mnew->length ) { Zinsert->state = CANTUSE; strcpy(Zinsert->task_name , Mnew->task_name); Zinsert->next = NULL; return 1; } else { struct MZone *Ztail = (struct MZone *)malloc(sizeof(struct MZone)); Zinsert->state = CANTUSE; strcpy(Zinsert->task_name , Mnew->task_name); Zinsert->length = Mnew->length; Zinsert->next = Ztail; memset( Ztail, 0, sizeof(char)*32 ); Ztail->begin_addr = Zinsert->begin_addr + Mnew->length; Ztail->state = CANUSE; Ztail->length = MSIZE - Ztail->begin_addr; Ztail->next = NULL; return 1; } } //memoreturn函数,用于回收内存 void memoreturn(void) { char tname[32]; printf("输入要收回的任务名\n"); scanf("%s",tname); Mreturn(tname); system("pause"); } //Mreturn函数,功能回收内存 int Mreturn(char taskname[]) { struct MZone *front = NULL; struct MZone *position = Mhead; struct MZone *tail = Mhead->next; while( 0!=strcmp(position->task_name,taskname) ) { front = position; if( NULL!=position->next ) { position = position->next; } else { position = NULL; break; } tail = position->next; } if( NULL==position ) { printf("内存中没有此任务!"); } else { //不能用CANTUSE if( NULL!=tail&&NULL!=front ) { if( front->state&&tail->state ) { front->length = front->length + position->length + tail->length; front->next = tail->next; free(position); free(tail); } else if( front->state&&!tail->state ) { front->length = front->length + position->length; front->next = position->next; free(position); } else if( !front->state&&tail->state ) { position->length = position->length + tail->length; memset( position->task_name, 0, sizeof(char)*32 ); position->next = tail->next; position->state = CANUSE; free(tail); } else if( !front->state&&!tail->state ) { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } } else if( NULL!=tail&&NULL==front ) { if( !tail->state ) { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } else { position->length = position->length + tail->length; position->next = NULL; free(tail); } } else if( NULL==tail&&NULL!=front ) { if(front->state) { front->length = front->length + position->length; front->next = NULL; free(position); } else { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } } else if( NULL==tail&&NULL==front ) { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } printf("内存回收成功!\n"); } } int main(void) { int func_ = 0; //初始化Mhead Mhead = (struct MZone*)malloc(sizeof(struct MZone)); Mhead->begin_addr = 0; Mhead->length = MSIZE; Mhead->state = CANUSE; memset(Mhead->task_name, 0, sizeof(char)*32 ); Mhead->next = NULL; while( 1 ) { printf("******************首次适应算法实现主存分配和回收系统(内存)***************"); printf("1:查看内存分配情况\n"); printf("2:申请分配内存\n"); printf("3:申请回收内存\n"); printf("4:退出程序\n"); printf("~~~~~~~~~~~~~~~~~"); scanf("%d",&func_); switch( func_ ) { case 1 :showmemory();break; case 2 :memoallocate();break; case 3 :memoreturn();break; case 4 :return 1; } system("cls"); } }
4. 运行结果及分析
图1.进入系统后有四个选项可以选择
图2.选择1查看内存分配情况
图3.选择2申请分配内存
图4.选择3申请回收内存
图5.回收内存后查看内存分配情况
四、实验总结
本次实验是通过链表的插入与输出来实现总体功能的,具体实现是靠各个函数来完成用户的选择。通过编写各个功能函数然后再主函数中调用实现,程序有一个较大的问题是用户如果不自主选择释放空间,分配出去的空间就不会在运行完之后自主回收,容易造成资源的浪费。通过本次实验,对之前的知识点掌握的更加牢固,接下来还是需要通过不断的练习来提高自己。