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

操作系统存储管理实验报告实验5存储管理第一,实验的目的1,加深对操作系统存储管理的理解2,可以过度模拟页面调试算法,加深对操作系统内存管理的理解二、一般设计思想、环境语言、工具等一般设计思想:1.编写一个函数来计算和输出以下算法的命中率:(1) OPT页面替换算法OPT选定的过时页面是已经转移到内存中并且将来不会被使用或者在最长时间内不会被访问的页面。
因此,如何找到这样的页面是算法的关键。
每页可以设置一个步长变量。
它的初始值是一个足够大的数字。
对于不在内存中的页面,其值将重置为零。
对于内存中的页面,其值被重置为当前访问的页面与页面首次出现时的距离。
因此,该值越大,在最长时间内不会被访问的页面就越多,并且可以选择它作为交换页面。
(2)先进先出页面替换算法先进先出总是选择首先进入内存的页面进行清除,因此可以设置先进先出的繁忙页面帧队列,新转移到内存的页面挂在队列的尾部,当没有空闲页面帧时,可以从队列的头部取出下一个页面帧作为空闲页面帧,然后再转移到需要的页面。
(3) LRU页面替换算法LRU 根据转移到存储器中的页面的使用做出决定。
它使用“最近的过去”作为“最近的未来”的近似,并选择最长时间没有使用的页面进行删除。
该算法主要通过页面结构中的访问时间来实现。
时间记录页面的最后访问时间。
因此,当需要删除一个页面时,选择时间值最小的页面,即最近最长时间没有使用的页面进行删除。
(4) LFU页面替换算法LFU要求每个页面配置一个计数器(即页面结构中的计数器)。
一旦页面被访问,计数器的值将增加1。
当需要替换一个页面时,将选择计数器值最小的页面,即存储器中访问次数最少的页面进行清除。
⑤NUR页面替换算法NUR要求为每个页面设置一个访问位(访问位仍然可以由页面结构中的计数器表示)。
当页面被访问时,其访问位计数器被设置为1。
当需要页面替换时,替换算法从替换指针(最初指向第一页)开始顺序检查内存中的每一页。
如果其访问位为0,则选择页面进行替换,否则,替换指针向下移动以继续向下搜索。
操作系统存储管理实验报告

实验五存储管理一、实验目的1 、加深对操作系统存储管理的理解2 、能过模似页面调试算法,加深理解操作系统对存的高度管理二、总的设计思想、环境语言、工具等总的设计思想:1、编写函数计算并输出下述各种算法的命中率①OPT页面置换算法OPT所选择被淘汰的页面是已调入存,且在以后永不使用的,或是在最长时间不再被访问的页面。
因此如找出这样的页面是该算法的关键。
可为每个页面设置一个步长变量,其初值为一足够大的数,对于不在存的页面,将其值重置为零,对于位于存的页面,其值重置为当前访问页面与之后首次出现该页面时两者之间的距离,因此该值越大表示该页是在最长时间不再被访问的页面,可以选择其作为换出页面。
②FIFO页面置换算法FIFO总是选择最先进入存的页面予以淘汰,因此可设置一个先进先出的忙页帧队列,新调入存的页面挂在该队列的尾部,而当无空闲页帧时,可从该队列首部取下一个页帧作为空闲页帧,进而调入所需页面。
③LRU页面置换算法LRU是根据页面调入存后的使用情况进行决策的,它利用“最近的过去”作为“最近的将来”的近似,选择最近最久未使用的页面予以淘汰。
该算法主要借助于页面结构中的访问时间time来实现,time记录了一个页面上次的访问时间,因此,当须淘汰一个页面时,选择处于存的页面中其time值最小的页面,即最近最久未使用的页面予以淘汰。
④LFU页面置换算法LFU要求为每个页面配置一个计数器(即页面结构中的counter),一旦某页被访问,则将其计数器的值加1,在需要选择一页置换时,则将选择其计数器值最小的页面,即存中访问次数最少的页面进行淘汰。
⑤NUR页面置换算法NUR要求为每个页面设置一位访问位(该访问位仍可使用页面结构中的counter 表示),当某页被访问时,其访问位counter置为1。
需要进行页面置换时,置换算法从替换指针开始(初始时指向第一个页面)顺序检查处于存中的各个页面,如果其访问位为0,就选择该页换出,否则替换指针下移继续向下查找。
北理工操作系统内存管理实验报告

实验三:内存管理班级:学号:姓名:一、实验目的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 ; }。
《操作系统》存储管理实验报告

____大学____学院实验报告课程名称:计算机操作系统实验名称:存储管理实验实验日期:班级:姓名:学号:仪器编号: XX实验报告要求:1.实验目的 2.实验要求 3.实验步骤 4.程序清单 5.运行情况6.流程图 7.实验体会1、实验目的①通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉虚存管理的各种页面淘汰法。
②通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。
2、实验要求①设计一个固定式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
可以假定每个作业都是批处理作业,并且不允许动态申请内存。
为实现分区的分配和回收,可以设定一个分区说明表,按照表中的有关信息进行分配,并根据分区的分配和回收情况修改该表。
②设计一个可变式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
对分区的管理法可以是下面三种算法之一:首次适应算法;最坏适应算法;最佳适应算法。
③编写并调试一个段页式存储管理的地址转换的模拟程序。
首先设计好段表、页表,然后给出若干个有一定代表性的地址,通过查找段表页表后得到转换的地址。
要求打印转换前的地址,相应的段表,页表条款及转换后的地址,以便检查。
3、实验步骤(1)理解实验要求,联系所学知识;(2)根据要求编写调度算法;(3)编写完整的实验代码并在VC++ 6.0环境下编译运行;(4)调试程序直至得出结果。
4、程序清单①#include <stdio.h>#include <stdio.h>#include<math.h>#include<stdlib.h>#define NUM 4#define alloMemory(type) (type*)malloc(sizeof(type)) struct partiTab{int no;int size;int firstAddr;char state;}parTab[NUM];typedef struct partiTab PARTITAB;typedef struct jcb { /*定义作业控制块JCB ,部分信息省略*/ char name[10]; //作业名int size; //作业大小struct jcb* link; //链指针}JCB;typedef struct{JCB *front,*rear;}jcbQue;jcbQue *jcbReadyQue;void AllocateMemory(int size);void createTab();void checkTab();void recycleMemory(int i);void AllocateMemory(int size){int i;for(i=0;i<NUM;i++){PARTITAB p=parTab[i];if(p.state='N' && p.size>size)parTab[i].state='Y';elseprintf("没有空闲分区,无法分配内存!\n"); }}void createTab(){int i;for( i=1;i<=NUM;i++){//getPartiTab(PARTITAB);parTab[i-1].no=i;parTab[i-1].size=20;parTab[i-1].firstAddr=21;parTab[i-1].state='N';}}void checkTab(){int i;printf("分区号\t大小\t起址\t状态\n");for(i=0;i<NUM;i++){printf("%d\t",parTab[i].no);printf("%d\t",parTab[i].size);printf("%d\t",parTab[i].firstAddr);printf("%c\t",parTab[i].state);printf("\n");}}void recycleMemory(int i){parTab[i-1].state='N';}int main(int argc, char* argv[]){int i;printf("\n\n\t\t*********************************************\t\t\n"); printf("\t\t\t\t实验一存储管理实验\n");printf("\t\t\t\t固定式分区分配存储管理\n");printf("\t\t*********************************************\t\t\n"); createTab();checkTab();printf("请按任意键继续:\n");getchar();printf("每个分区装入一道作业:\n");for(i=0;i<NUM;i++){AllocateMemory((i+1)*3);}checkTab();printf("请按任意键继续:\n");getchar();printf("假如一段时间后,其中一个作业结束,回收给它分配的分区(假如该作业在第2分区)\n");recycleMemory(2);checkTab();printf("请按任意键继续:\n");getchar();printf("接着,从外存后备作业队列中选择一个作业装入该分区(假如该作业大小为10)\n");AllocateMemory(10);checkTab();return 0;}#include<stdio.h>#include <dos.h>#include<stdlib.h>#include<conio.h>#define n 10#define m 10#define minisize 100struct{float address;float length;int flag;}used_table[n];struct{float address;float length;int flag;}free_table[m];void allocate(char J,float xk) {int i,k;float ad;k=-1;for(i=0; i<m; i++)if(free_table[i].length>=xk&&free_table[i].flag==1) if(k==-1||free_table[i].length<free_table[k].length) k=i;if(k==-1){printf("无可用空闲区\n");return;}if(free_table[k].length-xk<=minisize){free_table[k].flag=0;ad=free_table[k].address;xk=free_table[k].length;}else{free_table[k].length=free_table[k].length-xk;ad=free_table[k].address+free_table[k].length;}i=0;while(used_table[i].flag!=0&&i<n)i++;if(i>=n){printf("无表目填写已分分区,错误\n");if(free_table[k].flag==0)free_table[k].flag=1;else{free_table[k].length=free_table[k].length+xk;return;}}else{used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;}return;}void reclaim(char J){int i,k,j,s,t;float S,L;s=0;while((used_table[s].flag!=J||used_table[s].flag==0)&&s<n)s++;if(s>=n){printf("找不到该作业\n");return;}used_table[s].flag=0;S=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;while(i<m&&(j==-1||k==-1)){if(free_table[i].flag==1){if(free_table[i].address+free_table[i].length==S)k=i; if(free_table[i].address==S+L)j=i;}i++;}if(k!=-1)if(j!=-1) /* 上邻空闲区,下邻空闲区,三项合并*/ {free_table[k].length=free_table[j].length+free_table[k].length+L; free_table[j].flag=0;}else/*上邻空闲区,下邻非空闲区,与上邻合并*/free_table[k].length=free_table[k].length+L;else if(j!=-1) /*上邻非空闲区,下邻为空闲区,与下邻合并*/{free_table[j].address=S;free_table[j].length=free_table[j].length+L;}else /*上下邻均为非空闲区,回收区域直接填入*/{/*在空闲区表中寻找空栏目*/t=0;while(free_table[t].flag==1&&t<m)t++;if(t>=m) /*空闲区表满,回收空间失败,将已分配表复原*/{printf("主存空闲表没有空间,回收空间失败\n");used_table[s].flag=J;return;}free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;}return;}/*主存回收函数结束*/int main( ){printf("\n\n\t\t*********************************************\t\t\n"); printf("\t\t\t\t实验三存储管理实验\n");printf("\n\t\t\t可变式分区分配 (最佳适应算法)\n");printf("\t\t*********************************************\n");int i,a;float xk;char J;/*空闲分区表初始化:*/free_table[0].address=10240; /*起始地址假定为10240*/free_table[0].length=10240; /*长度假定为10240,即10k*/free_table[0].flag=1; /*初始空闲区为一个整体空闲区*/for(i=1; i<m; i++)free_table[i].flag=0; /*其余空闲分区表项未被使用*//*已分配表初始化:*/for(i=0; i<n; i++)used_table[i].flag=0; /*初始时均未分配*/{printf("功能选择项:\n1。
内存管理实验报告

内存管理实验报告实验名称:内存管理实验目的:掌握内存管理的相关概念和算法加深对内存管理的理解实验原理:内存管理是操作系统中的一个重要模块,负责分配和回收系统的内存资源。
内存管理的目的是高效地利用系统内存,提高系统的性能和稳定性。
实验过程:1.实验环境准备本实验使用C语言编程,要求安装GCC编译器和Linux操作系统。
2.实验内容实验主要包括以下几个部分:a.基本内存管理创建一个进程结构体,并为其分配一定大小的内存空间。
可以通过C语言中的指针操作来模拟内存管理的过程。
b.连续分配内存算法实现两种连续分配内存的算法:首次适应算法和最佳适应算法。
首次适应算法是从低地址开始寻找满足要求的空闲块,最佳适应算法是从所有空闲块中选择最小的满足要求的块。
c.非连续分配内存算法实现分页和分段两种非连续分配内存的算法。
分页是将进程的虚拟地址空间划分为固定大小的页面,然后将页面映射到物理内存中。
分段是将进程的地址空间划分为若干个段,每个段可以是可变大小的。
3.实验结果分析使用实验中的算法和方法,可以实现对系统内存的高效管理。
通过比较不同算法的性能指标,我们可以选择合适的算法来满足系统的需求。
具体而言,连续分配内存算法中,首次适应算法适用于内存中有大量小碎片的情况,可以快速找到满足要求的空闲块。
最佳适应算法适用于内存中碎片较少的情况,可以保证最小的内存浪费。
非连续分配内存算法中,分页算法适用于对内存空间的快速分配和回收,但会带来一定的页表管理开销。
分段算法适用于对进程的地址空间进行分段管理,可以灵活地控制不同段的权限和大小。
实验中还可以通过性能测试和实际应用场景的模拟来评估算法的性能和适用性。
实验总结:本实验主要介绍了内存管理的相关概念和算法,通过编写相应的代码实现了基本内存管理和连续分配、非连续分配内存的算法。
通过实际的实验操作,加深了对内存管理的理解。
在实验过程中,我们发现不同算法适用于不同情况下的内存管理。
连续分配算法可以根据实际情况选择首次适应算法或最佳适应算法。
操作系统:实验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()函数,如果函数成功,则获得大块内存,但不将任何物理内存调配到此块中。
实验四 操作系统存储管理实验报告

实验四操作系统存储管理实验报告一、实验目的本次操作系统存储管理实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配、回收、地址转换等关键技术,提高对操作系统存储管理机制的认识和应用能力。
二、实验环境操作系统:Windows 10开发工具:Visual Studio 2019三、实验原理1、内存分配方式连续分配:分为单一连续分配和分区式分配(固定分区和动态分区)。
离散分配:分页存储管理、分段存储管理、段页式存储管理。
2、内存回收算法首次适应算法:从内存低地址开始查找,找到第一个满足要求的空闲分区进行分配。
最佳适应算法:选择大小最接近作业需求的空闲分区进行分配。
最坏适应算法:选择最大的空闲分区进行分配。
3、地址转换逻辑地址到物理地址的转换:在分页存储管理中,通过页表实现;在分段存储管理中,通过段表实现。
四、实验内容及步骤1、连续内存分配实验设计一个简单的内存分配程序,模拟固定分区和动态分区两种分配方式。
输入作业的大小和请求分配的分区类型,程序输出分配的结果(成功或失败)以及分配后的内存状态。
2、内存回收实验在上述连续内存分配实验的基础上,添加内存回收功能。
输入要回收的作业号,程序执行回收操作,并输出回收后的内存状态。
3、离散内存分配实验实现分页存储管理的地址转换功能。
输入逻辑地址,程序计算并输出对应的物理地址。
4、存储管理算法比较实验分别使用首次适应算法、最佳适应算法和最坏适应算法进行内存分配和回收操作。
记录不同算法在不同作业序列下的内存利用率和分配时间,比较它们的性能。
五、实验结果与分析1、连续内存分配实验结果固定分区分配方式:在固定分区大小的情况下,对于作业大小小于或等于分区大小的请求能够成功分配,否则分配失败。
内存状态显示清晰,分区的使用和空闲情况一目了然。
动态分区分配方式:能够根据作业的大小动态地分配内存,但容易产生内存碎片。
2、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。
操作系统存储管理实验报告

操作系统存储管理实验报告一、实验目的操作系统的存储管理是计算机系统中非常重要的组成部分,它直接影响着系统的性能和资源利用率。
本次实验的目的在于深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握存储分配、回收、地址转换等关键技术,并对不同存储管理策略的性能进行分析和比较。
二、实验环境本次实验在 Windows 10 操作系统下进行,使用 Visual Studio 2019 作为编程环境,编程语言为 C++。
三、实验内容(一)固定分区存储管理1、原理固定分区存储管理将内存空间划分为若干个固定大小的分区,每个分区只能装入一道作业。
分区的大小可以相等,也可以不等。
2、实现创建一个固定大小的内存空间数组,模拟内存分区。
为每个分区设置状态标志(已分配或空闲),并实现作业的分配和回收算法。
3、实验结果与分析通过输入不同大小的作业请求,观察内存的分配和回收情况。
分析固定分区存储管理的优缺点,如内存利用率低、存在内部碎片等。
(二)可变分区存储管理1、原理可变分区存储管理根据作业的实际需求动态地划分内存空间,分区的大小和数量是可变的。
2、实现使用链表或数组来管理内存空间,记录每个分区的起始地址、大小和状态。
实现首次适应、最佳适应和最坏适应等分配算法,以及分区的合并和回收算法。
3、实验结果与分析比较不同分配算法的性能,如分配时间、内存利用率等。
观察内存碎片的产生和处理情况,分析可变分区存储管理的优缺点。
(三)页式存储管理1、原理页式存储管理将内存空间和作业都划分为固定大小的页,通过页表将逻辑地址转换为物理地址。
2、实现设计页表结构,实现逻辑地址到物理地址的转换算法。
模拟页面的调入和调出过程,处理缺页中断。
3、实验结果与分析测量页式存储管理的页面置换算法(如先进先出、最近最少使用等)的命中率,分析其对系统性能的影响。
探讨页大小的选择对存储管理的影响。
(四)段式存储管理1、原理段式存储管理将作业按照逻辑结构划分为若干个段,每个段有自己的名字和长度。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三:内存管理班级:学号:姓名:一、实验目的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 ; }。