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

合集下载

内存管理实验报告

内存管理实验报告
图 1 MEM_RESERVE
图 2 MEM_COMMIT
图 3 MEM_RELEASE
操作系统实验——内存管理
计算机 B 班 吴为丹 033511081
图 4 LOCK
图 5 UNLOCK
图 6 MEM_RESET
图 7 MEM_TOP_DOWN 操作失败
d) 有以下几种情况时,操作没有进行,要求释放内存而没有已经分配的内存;要求回 收内存而没有已经保留或分配的内存;要求加锁而没有已经分配的内存;要求解锁而没 有已经加锁的内存。如图 3、图 4 和图 5 所示。
z 实验改进
增加内存分配的类型,如 MEM_TOP_DOWN、MEM_RESET,增加保护级别的类型,如 PAGE_GUARD、PAGE_NOACCESS、PAGE_NOCACHE,运行结果正常,如上图所示。
8) WaitForMultipleObjects 函数功能:当满足下列条件之一时返回:(1)任意一个或全部指定对象处于信号态;(2)超 时。 在本实验中用于结束主程序。 函数原型:DWORD WaitForMultipleObject(DWORD ncount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds);
// 2:释放(释放已分配内存,但仍然保留); // 3:回收(回收已分配或已保留内存);4:加锁;5:解锁 // 具体数值见数组 TYPE(main.cpp) int Protect; // 0:PAGE_READONLY;1:PAGE_READWRITE;2:PAGE_EXECUTE;
// 3:PAGE_EXECUTE_READ;4:PAGE_EXECUTE_READWRITE // 具体数值见数组 PRO(main.cpp) }; 2) 内存块 struct RESER{ //记录已保留内存 LPVOID lpvoid; DWORD size; }; struct COMMIT{ //记录已分配内存 LPVOID lpvoid; DWORD size; }; struct LOCK{ //记录已加锁内存 LPVOID lpvoid; DWORD size; }; 3. 相关 windows API 函数 1) GlobalMemoryStatus 函数功能:获得计算机系统中当前使用的物理内存和虚拟内存的信息 函数原型:VOID GlobalMemoryStatus (LPMEMORYSTATUS lpBuffer); 函数参数:lpBuffer 是指向 MEMORYSTATUS 结构的指针,_MEMORYSTATUS 结构用来存 储系统内存信息,具体内容见下文“相关数据结构”。 返回值:无(在结构变量中)

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

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

操作系统存储管理实验报告实验5存储管理第一,实验的目的1,加深对操作系统存储管理的理解2,可以过度模拟页面调试算法,加深对操作系统内存管理的理解二、一般设计思想、环境语言、工具等一般设计思想:1.编写一个函数来计算和输出以下算法的命中率:(1) OPT页面替换算法OPT选定的过时页面是已经转移到内存中并且将来不会被使用或者在最长时间内不会被访问的页面。

因此,如何找到这样的页面是算法的关键。

每页可以设置一个步长变量。

它的初始值是一个足够大的数字。

对于不在内存中的页面,其值将重置为零。

对于内存中的页面,其值被重置为当前访问的页面与页面首次出现时的距离。

因此,该值越大,在最长时间内不会被访问的页面就越多,并且可以选择它作为交换页面。

(2)先进先出页面替换算法先进先出总是选择首先进入内存的页面进行清除,因此可以设置先进先出的繁忙页面帧队列,新转移到内存的页面挂在队列的尾部,当没有空闲页面帧时,可以从队列的头部取出下一个页面帧作为空闲页面帧,然后再转移到需要的页面。

(3) LRU页面替换算法LRU 根据转移到存储器中的页面的使用做出决定。

它使用“最近的过去”作为“最近的未来”的近似,并选择最长时间没有使用的页面进行删除。

该算法主要通过页面结构中的访问时间来实现。

时间记录页面的最后访问时间。

因此,当需要删除一个页面时,选择时间值最小的页面,即最近最长时间没有使用的页面进行删除。

(4) LFU页面替换算法LFU要求每个页面配置一个计数器(即页面结构中的计数器)。

一旦页面被访问,计数器的值将增加1。

当需要替换一个页面时,将选择计数器值最小的页面,即存储器中访问次数最少的页面进行清除。

⑤NUR页面替换算法NUR要求为每个页面设置一个访问位(访问位仍然可以由页面结构中的计数器表示)。

当页面被访问时,其访问位计数器被设置为1。

当需要页面替换时,替换算法从替换指针(最初指向第一页)开始顺序检查内存中的每一页。

如果其访问位为0,则选择页面进行替换,否则,替换指针向下移动以继续向下搜索。

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

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

同组同学学号:#include <stdio.h>#include <malloc.h>#include <string.h>int main(void){char *str; /* 为字符串申请分配一块内存 */if ((str = (char *) malloc(10)) == NULL){printf("Not enough memory to allocate buffer\n");return(1); /* 若失败则结束程序 */} /* 复制 "Hello" 字符串到分配到的内存 */strcpy(str, "Hello"); /* 打印出字符串和其所在的地址 */printf("String is %s\n Address is %p\n", str, str); /* 重分配刚才申请到的内存空间, 申请增大一倍 */if ((str = (char *) realloc(str, 20)) == NULL) { printf("Not enough memory to allocate buffer\n"); return(1); /* 监测申请结果, 若失败则结束程序, 养成这个好习惯 */} /* 打印出重分配后的地址 */printf("String is %s\n New address is %p\n", str, str); /* 释放内存空间 */free(str);return 0;}调试过后得出结果截图如下:#include <stdio.h>#include <alloca.h>void test(int a){char *newstack;/* 申请一块内存空间*/newstack = (char *) alloca(len);if (newstack)/* 若成功, 则打印出空间大小和起始地址*/ printf("Alloca(0x%X) returned %p\n",len,newstack);else/* 失败则报告错误, 我们是做实验, 目前无需退出*/ printf("Alloca(0x%X) failed\n",len);} /* 函数退出, 内存自动释放, 无需干预*/void main(){/* 申请一块256字节大小的内存空间, 观察输出情况*/ test(256);/* 再申请一块更大内存空间, 观察输出情况*/test(16384);}调试结果截图如下:根据练习二改编程序如下:#include <stdio.h>#include <malloc.h>#include <string.h>int main(void){char *str;/* 为字符串申请分配一块内存 */if ((str = (char *) malloc(20)) == NULL){printf("Not enough memory to allocate buffer\n"); return(1); /* 若失败则结束程序 */}/* 复制 "Hello" 字符串到分配到的内存 */strcpy(str, "My name is Li Caihong!");/* 打印出字符串和其所在的地址 */printf("String is %s\n Address is %p\n", str, str); /* 重分配刚才申请到的内存空间, 申请增大一倍 */if ((str = (char *) realloc(str, 40)) == NULL){ printf("Not enough memory to allocate buffer\n"); return(1);/* 监测申请结果, 若失败则结束程序, 养成这个好习惯 */}/* 打印出重分配后的地址 */printf("String is %s\n New address is %p\n", str, str);/* 释放内存空间*/free(str);return 0; }在该程序中, 我将程序中的“Hello”改为“My name is Li Caihong!”首次调试出来的结果显示内存太小, 出现的结果有很多不认识的代码。

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

操作系统“内存管理”实验报告
initpcb();
initpart();
printf("\t****************Hale Waihona Puke ***********MENU**
**************************\n");
printf("\t************** Enter: r 请求分配内存**************\n");
%d\n",pcbl->PCBelem[i].name,pcbl->
PCBelem[i].address,pcbl->PCBelem[i].len);
}
printf("当前的空闲分区有:\n");
printf("address length\n");
for(i=0;i<maxPart;i++)
{
if(partl->Partelem[i].valid==1)
for(i=1;i<maxPart;i++)
{
partl->Partelem[i].address=0;
partl->Partelem[i].len=0;
partl->Partelem[i].valid=0;
}
partl->sum=1;
}
voidrequest(charname,intlen)//进程name请求len大小的内存
printf("\t************** Enter: s 结束进程 **************\n");
printf("\t************** Enter: p 打印分配情况**************\n");

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

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

实验三:内存管理班级:学号:姓名:一、实验目的1.通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解;2.熟悉虚存管理的页面淘汰算法;3.通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。

二、实验要求1.设计一个请求页式存储管理方案(自己指定页面大小),并予以程序实现。

并产生一个需要访问的指令地址流。

它是一系列需要访问的指令的地址。

为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列。

2.页面淘汰算法采用FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。

而不再判断它是否被改写过,也不将它写回到辅存。

3.系统运行既可以在Windows,也可以在Linux。

三、实验流程图图1 页式存储管理程序参考流程四、实验环境硬件设备:个人计算机。

系统软件:windows操作系统,Visual C++6.0编译环境。

五、实验结果说明:模拟产生35个指令地址,随机产生20个指令地址进行排队,假设主存中共有10个工作集页帧。

将前9个指令调入内存,因为前9个指令中,页号为13的指令有两个,所以调入内存中共有8页。

此时主存中还有两个空闲帧。

此时按刚才随机顺序进行访问指令工作。

前9页因都在主存中可直接调用。

第10个随机地址为页号为5的指令,也在主存中,也可直接调用。

页号为24,3因不在主存中,需要调用进主存。

此时主存已满。

然后主存需要进行调用页号为27号的指令,因主存已满,需要执行FIFO算法,将最先进入主存的页号为30的指令调出,将27号放入第1000000帧。

以后需要调用的页面按照存在就无需调用,否则按FIFO原则进行调页工作。

六、实验感想七、实验代码#include <iostream>#include <iomanip>#include <stdlib.h>#include <time.h>#include <vector>#include <queue>//#include <algorithm>using namespace std ;#define PAGETABLE_NUM 35 //模拟进程的页表表项数量;#define AVAILABLEFRAME_NUM 10 //主存中固定工作集页帧的数量;#define RANDOMNUMBER_NUM 20 //产生随机指令地址的数量;structPageTableEntry{unsignedintFrameNum ;boolPressent ;};voidInitRandomAddr(vector<unsigned int>&RandomAddr) ;voidInitIdleFrameQueue(queue<unsigned int>&IdleFrameQueue) ;voidInitPageTable(vector<PageTableEntry>&PageTable, vector<unsigned int>&RandomAddr, queue<unsigned int>&IdleFrameQueue, queue<unsigned int>&AvtiveFrameQueue) ;voidSetPTE(PageTableEntry&PTE) ;int main(){int a ;//初始化RANDERNUMBER_NUM条随机的32位指令地址;vector<unsigned int>RandomAddr(RANDOMNUMBER_NUM) ;InitRandomAddr(RandomAddr) ;//初始化FIFS指针;vector<unsigned int>::iterator FIFS_pintor ;FIFS_pintor = RandomAddr.begin() ;//初始空闲帧队列;queue<unsigned int>IdleFrameQueue, ActiveFrameQueue ;InitIdleFrameQueue(IdleFrameQueue) ;//初始进程页表(模拟进程初始时,工作集已经使用至少10个页帧);vector<PageTableEntry>PageTable(PAGETABLE_NUM) ;InitPageTable(PageTable, RandomAddr, IdleFrameQueue, ActiveFrameQueue) ;//Testcout<<" 开始访问指令地址\n" ;vector<unsigned int>::iterator pt_RandomAddr ;for(pt_RandomAddr = RandomAddr.begin(); pt_RandomAddr != RandomAddr.end(); pt_RandomAddr++ ){unsignedintPageNum = (*pt_RandomAddr) >> 12 ;cout<<"地址:0x"<<hex<<*pt_RandomAddr<<dec<<"\t页号:"<<PageNum;if ( PageTable[PageNum].Pressent == 0 ) //该页不在主存中;{cout<<"\t该页不在主存,";if (IdleFrameQueue.empty()) //工作集空闲页帧已用完;{cout<<"执行FIFO淘汰算法\t";//FIFS算法淘汰一页;unsignedintFrame_Num ;Frame_Num = ActiveFrameQueue.front() ;ActiveFrameQueue.pop() ;PageTable[(*FIFS_pintor) >> 12].Pressent = 0 ; //标记此页已经被置换出主存;//置换进新页;PageTable[PageNum].FrameNum = Frame_Num ;PageTable[PageNum].Pressent = 1 ;ActiveFrameQueue.push(Frame_Num) ;//移动FIFS指针;FIFS_pintor++ ;}else{cout<<"调入所需页到空闲页\t";//调入当前所需的页到空闲页中;unsignedintFrame_Num ;Frame_Num = IdleFrameQueue.front() ;IdleFrameQueue.pop() ;PageTable[PageNum].FrameNum = Frame_Num ;PageTable[PageNum].Pressent = 1 ;ActiveFrameQueue.push(Frame_Num) ;}}elsecout<<"\t该页在主存";cout<<"\t帧号:"<<PageTable[PageNum].FrameNum<<endl ;}return 0 ;}voidInitRandomAddr(vector<unsigned int>&RandomAddr){cout<<" 生成随机指令地址\n" ;vector<unsigned int>::iterator pd ;srand( (unsigned)time( NULL ) );for(pd = RandomAddr.begin(); pd != RandomAddr.end(); pd++ ){//产生随机页号0~PAGETABLE_NUM - 1;unsignedint High_20 = rand() % PAGETABLE_NUM ;//产生随机偏移量0~4095 ;unsignedint Low_12 = rand() % 4096 ;unsignedintAddr = (High_20 << 12) | Low_12 ;*pd = Addr ;cout<<"随机指令地址:0x"<<setw(8)<<setfill('0') <<setiosflags(ios::uppercase | ios::fixed)<<hex<<*pd<<"\t页号:"<<dec<<High_20<<"\t偏移量:0x"<<hex<<Low_12<<dec<<endl ;}}voidInitIdleFrameQueue(queue<unsigned int>&IdleFrameQueue){//帧号从0~1048575,这里取1000000~1000016;for ( unsigned intFrameNum = 1000000; FrameNum< 1000000 + AVAILABLEFRAME_NUM; FrameNum++ )IdleFrameQueue.push(FrameNum) ;}voidInitPageTable(vector<PageTableEntry>&PageTable, vector<unsigned int>&RandomAddr, queue<unsigned int>&IdleFrameQueue, queue<unsigned int>&AvtiveFrameQueue){cout<<" 初始化页表; \n" ;for_each(PageTable.begin(), PageTable.end(), SetPTE) ;unsignedintPage_Num, Frame_Num ;for ( int count = 0; count < 9; count++){while(true){Page_Num = RandomAddr[count] >> 12 ;if ( PageTable[Page_Num].Pressent != 0 )break ;Frame_Num = IdleFrameQueue.front() ;IdleFrameQueue.pop() ;PageTable[Page_Num].FrameNum = Frame_Num ; //设置页帧号;PageTable[Page_Num].Pressent = 1 ; //标记页帧在主存中;AvtiveFrameQueue.push(Frame_Num) ; //记录活动页帧;cout<<"将模拟进程的第"<<Page_Num<<"页初始化至主存中,帧号为:"<<Frame_Num<<endl;}}cout<<endl ;}voidSetPTE(PageTableEntry&PTE){PTE.FrameNum = PTE.Pressent = 0 ; }。

内存管理实验报告

内存管理实验报告

内存管理实验报告实验名称:内存管理实验目的:掌握内存管理的相关概念和算法加深对内存管理的理解实验原理:内存管理是操作系统中的一个重要模块,负责分配和回收系统的内存资源。

内存管理的目的是高效地利用系统内存,提高系统的性能和稳定性。

实验过程:1.实验环境准备本实验使用C语言编程,要求安装GCC编译器和Linux操作系统。

2.实验内容实验主要包括以下几个部分:a.基本内存管理创建一个进程结构体,并为其分配一定大小的内存空间。

可以通过C语言中的指针操作来模拟内存管理的过程。

b.连续分配内存算法实现两种连续分配内存的算法:首次适应算法和最佳适应算法。

首次适应算法是从低地址开始寻找满足要求的空闲块,最佳适应算法是从所有空闲块中选择最小的满足要求的块。

c.非连续分配内存算法实现分页和分段两种非连续分配内存的算法。

分页是将进程的虚拟地址空间划分为固定大小的页面,然后将页面映射到物理内存中。

分段是将进程的地址空间划分为若干个段,每个段可以是可变大小的。

3.实验结果分析使用实验中的算法和方法,可以实现对系统内存的高效管理。

通过比较不同算法的性能指标,我们可以选择合适的算法来满足系统的需求。

具体而言,连续分配内存算法中,首次适应算法适用于内存中有大量小碎片的情况,可以快速找到满足要求的空闲块。

最佳适应算法适用于内存中碎片较少的情况,可以保证最小的内存浪费。

非连续分配内存算法中,分页算法适用于对内存空间的快速分配和回收,但会带来一定的页表管理开销。

分段算法适用于对进程的地址空间进行分段管理,可以灵活地控制不同段的权限和大小。

实验中还可以通过性能测试和实际应用场景的模拟来评估算法的性能和适用性。

实验总结:本实验主要介绍了内存管理的相关概念和算法,通过编写相应的代码实现了基本内存管理和连续分配、非连续分配内存的算法。

通过实际的实验操作,加深了对内存管理的理解。

在实验过程中,我们发现不同算法适用于不同情况下的内存管理。

连续分配算法可以根据实际情况选择首次适应算法或最佳适应算法。

操作系统:实验4 存储管理(实验报告)

操作系统:实验4 存储管理(实验报告)

欢迎共阅班级: 姓名: 学号:5) 当前计算机的实际内存大小为:______________________________________ 分析程序4-1,请回答问题:1) 理论上每个Windows 应用程序可以独占的最大存储空间是:_____________2) 程序中,用于检查系统中虚拟内存特性的API 函数是:__________________ 4.2 Windows 虚拟内存本节实验的目的是:实验4存储管理1) 通过实验了解Windows内存的使用,学习如何在应用程序中管理内存,体会Windows应用程序内存的简单性和自我防护能力。

2) 学习检查虚拟内存空间或对其进行操作;3) 了解Windows的内存结构和虚拟内存的管理,进而了解进程堆和Windows为使用内存而提供的一些扩展功能。

1. 工具/准备工作在开始本节实验之前,请回顾教材的相关内容。

需要准备一台运行Windows系统的计算机,且安装了C/C++编译器。

2. 实验内容与步骤将系统当前的保留区(reserved)虚拟地址空间填入表4.3中。

表4.3 实验记录2) 根据运行结果,请简单描述程序运行的流程:_________________________________________________________________________________________________________________________________________的程序段,该段程序试图通过VirtualAlloc()函数,然后利用物理备用内存将整个块分配到虚拟内存空间的任何位置。

这种技术只对拥有1GB以上的RAM且都有换页文件的计算机可行。

从运行结果看,这种技术成功了吗?_________________。

3) 程序中说明为___________________________________________________的程序段,该段程序利用VirtualAlloc()函数,如果函数成功,则获得大块内存,但不将任何物理内存调配到此块中。

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

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

操作系统存储管理实验报告一、实验目的本次实验的目的是通过编写一段程序,实现对内存的分配和回收操作,并验证算法的正确性和性能。

二、实验内容1.实现首次适应算法首次适应算法是一种动态分配的内存管理算法,通过从低地址往高地址内存块,找到第一个满足需求的空闲块进行分配。

具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,根据需求大小找到第一个合适的空闲块,并在其前后设置相应的标志位;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。

2.实现最佳适应算法最佳适应算法是一种动态分配的内存管理算法,通过整个内存空间,找到最小的满足需求的空闲块进行分配。

具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,遍历整个内存空间,找到满足需求且大小最小的空闲块进行分配;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。

三、实验结果1.首次适应算法经过测试,首次适应算法能够正确地进行内存的分配和回收操作,并且算法的性能良好。

尽管首次适应算法在分配过程中可能会产生碎片,但是由于它从低地址开始,可以在较短的时间内找到满足需求的空闲块。

在实际应用中,首次适应算法被广泛采用。

2.最佳适应算法经过测试,最佳适应算法能够正确地进行内存的分配和回收操作,并且算法的性能较好。

最佳适应算法会整个内存空间,找到大小最小的满足需求的空闲块。

因此,在分配过程中不会产生很多的碎片,但是算法的执行时间较长。

四、实验总结通过本次实验,我们成功地实现了首次适应算法和最佳适应算法,并对算法的正确性和性能进行了验证。

两种算法在内存的分配和回收过程中都表现出良好的性能,可广泛应用于实际场景中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
尽可能的利用了低地址空间,从而保证高地址有较大的空闲区来防止要求 内存较多的进程或作业
该算法的分配和释放的时间性能较好 最佳适应法:
利用最接近于所要求的内存大小。若存储空间中有正好等于所要求大小的 空白区,则必然被选中。
由于空白区一般不可能正好和要求的相等,这往往使剩下的空白区都比较 小,形成碎片。
四、开发工具及主要源代码
1、开发工具
sublimeText3 文本编辑器,采用 g++编译。
2、主要源码
这里只给出最先适应算法的源码,由于三种算法均为对链表进行排序,只是 排序依据的属性不同,结构上几乎相似,在此就不做赘述 /*最先适应算法,按地址的大小由小到达排序*/
void rFirst_Fit() {
采用最先适应法新建一个大小为 16 的进程,结果如上图所示。
采用最佳适应法插入一个大小为 7 的进程后内存的情况。 分析:此处对于内存管理的模拟实现完成的较为成功,可以采用最先适应法和 最佳适应法两种算法进行进程的新建,能够正确计算对应的首地址,与内存空 间。同时对于空闲内存空间也可以做出正确的合并操作。最初内存空间为空, 可以通过新建进程和终止进程两种操作来完成不连续内存空闲空间的建立。 三种算法的比较: 最先适应法:
二、问题描述
所谓分区,是把内存分为一些大小相等或不等的分区,除操作系统占用一 个分区外,其余分区用来存放进程的程序和数据。本次实验中才用动态分区 法,也就是在作业的处理过程中划分内存的区域,根据需要确定大小。
动态分区的分配算法:首先从可用表/自由链中找到一个足以容纳该作业的 可用空白区,如果这个空白区比需求大,则将它分为两个部分,一部分成为已 分配区,剩下部分仍为空白区。最后修改可用表或自由链,并回送一个所分配 区的序号或该分区的起始地址。
if (temp->next->start_addr < current_min_addr) {
current_min_addr = temp->next->start_addr; p = temp; } temp = temp->next; } if (p != NULL) { temp = p->next; p->next = p->next->next; temp->next = free_block; free_block = temp; } head = free_block; p = head; temp = head->next; while (head->next != NULL) { current_min_addr = head->next->start_addr; while (temp->next != NULL) { if (temp->next->start_addr < current_min_addr) {
该模块完成在内存空间中申请一块空间供进程使用的功能,通过输入进程大 小系统先查看内存空间中是否有足够的空间供其进行申请,若无,显示分配失败 相应信息,否则在空闲内存分区块中选择最先的一块进行分配,若内存空间不足 则继续向下查找,空闲内存分区的顺序通过三种算法给出。分配内存时,要指定 进程的首地址和大小,并对内存空闲分区的大小做相应的修改。 2.4 进程终止模块
况。其中 pid 作为该被分配分区的编号,用于在释放该内存空间时便于查找。
size 表示分区的大,start_addr 表示分区的起始地址,process_name 存放进
程名称,next 指针指向下一个分区。
//已分配分区的结构体 typedef struct Allocate_Block {
int pid; int size; int start_addr; char process_name[PROCESS_NAME_LEN]; struct Allocate_Block *next; } Allocate_Block;
//空闲分区 typedef struct Free_Block {
int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block;
定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情
head->next = temp; } head = head->next; temp = head->next; p = head; } } return ; } //创建一个新的进程 int New_Job() { struct Allocate_Block *ab; int size; int ret; ab = (struct Allocate_Block *)malloc(sizeof(struct Allocate_Block)); if (!ab) exit(-5); ab->next = NULL; pid++; sprintf(ab->process_name, "进程-%02d", pid); ab->pid = pid; printf("Mem for %s:", ab->process_name); printf(" 进程大小 : "); scanf("%d", &size); if (size > 0) {
最先适应法:按分区的起始地址的递增次序,从头查找,找到符合要求的 第一个分区。
最佳适应法:按照分区大小的递增次序,查找,找到符合要求的第一个分
区。
最坏适应法:按分区大小的递减次序,从头查找,找到符合要求的第一个
分区。
三、数据结构及功能设计
1、数据结构
定义空闲分区结构体,用来保存内存中空闲分区的情况。其中 size 属性表示 空闲分区的大小,start_addr 表示空闲分区首地址,next 指针指向下一个空闲分 区。
模拟实现内存管理机制
3、具体要求 任选一种计算机高级语言编程实现 选择一种内存管理方案:动态分区式、请求页式、段式、段页式
等 能够输入给定的内存大小,进程的个数,每个进程所需内存空间
的大小等 能够选择分配、回收操作 内购显示进程在内存的储存地址、大小等 显示每次完成内存分配或回收后内存空间的使用情况
五、测试用例及运行结果、分析
程序最初要对内存空间进行分配,设置内存空间的大小。初始设置内存总 大小为 100 个单位,若不手动设置,则默认为 256 个单位。
此为最初插入 7 个进程后的内存状态,此时内存空间无空余块可用。
通过进程终止操作将 pid 为 1、3、5、7 四个进程终止,则其原占用的内存 空间释放,变为空闲的内存空间。
Free_Block *temp, *p = NULL; Free_Block *head = NULL; int current_min_addr;
if (free_block) {
temp = free_block; current_min_addr = free_block->start_addr; while (temp->next != NULL) {
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;
不足之处在于,本次实验中没有实现最坏适应法,分析可能是在在排序的 过程中链表的指针出现了错误,在开始调试阶段只对单一算法进行了调试从而 忽略了这个问题的存在,直到编写本报告的时候才发现这个问题。这种问题实 属不该,可以通过完善的测试避免,以后要避免这种问题。
本次实验通过对于内存管理的动态分区式算法实现,对这内存管理的理解 更加深刻了,也通过实验结果的比较,掌握了动态分区式内存管理中三种算法 在不同进程情况下的优劣情况。通过这样一个一个小实验,也一定程度上锻炼 了我的编程能力。
2、模块说明
2.1 初始化模块
对内存空间进行初始化,初始情况内存空间为空,但是要设置内存的最大容
量,该内存空间的首地址,以便之后新建进程的过程中使用。当空闲分区初始化
失败时,要进行相应的提示。 2.2 菜单显示模块
菜单包括,设置内存大小,选择分配算法,新建进程,终止进程,显示当前 内存使用情况,退出六个选项。各个选项完成其名对应的功能,在程序中通过相 应的函数实现对应的功能。 2.3 新建进程模块
学生学号
实验课成绩
武汉理工大学
学生实验报告书
实验课程名称 开课学院 指导老师姓名 学生姓名 学生专业班级
计算机操作系统 计算机科学与技术学院
2016 — 2017 学年 第一学期
实验三 内存管理
一、设计目的、功能与要求
1、实验目的
掌握内存管理的相关内容,对内存的分配和回收有深入的理解。
2、实现功能
ab->size = size; } ret = Alloc_Mem(ab); if ((ret == 1) && (Allocate_Block_head == NULL)) {
Allocate_Block_head = ab; return 1; }
else if (ret == 1) {
ab->next = Allocate_Block_head; Allocate_Block_head = ab; return 2; } else if (ret == -1) {
寻找一个较大的空白区时,要花费较多的时间;回收一个分区时,为了把 它插入到空白区链中合适的位置上开销较大。 最坏适应法:
相关文档
最新文档