佛山科学技术学院-操作系统-存储管理-实验报告
- 格式:pdf
- 大小:268.07 KB
- 文档页数:23
操作系统存储管理实验报告实验5存储管理第一,实验的目的1,加深对操作系统存储管理的理解2,可以过度模拟页面调试算法,加深对操作系统内存管理的理解二、一般设计思想、环境语言、工具等一般设计思想:1.编写一个函数来计算和输出以下算法的命中率:(1) OPT页面替换算法OPT选定的过时页面是已经转移到内存中并且将来不会被使用或者在最长时间内不会被访问的页面。
因此,如何找到这样的页面是算法的关键。
每页可以设置一个步长变量。
它的初始值是一个足够大的数字。
对于不在内存中的页面,其值将重置为零。
对于内存中的页面,其值被重置为当前访问的页面与页面首次出现时的距离。
因此,该值越大,在最长时间内不会被访问的页面就越多,并且可以选择它作为交换页面。
(2)先进先出页面替换算法先进先出总是选择首先进入内存的页面进行清除,因此可以设置先进先出的繁忙页面帧队列,新转移到内存的页面挂在队列的尾部,当没有空闲页面帧时,可以从队列的头部取出下一个页面帧作为空闲页面帧,然后再转移到需要的页面。
(3) LRU页面替换算法LRU 根据转移到存储器中的页面的使用做出决定。
它使用“最近的过去”作为“最近的未来”的近似,并选择最长时间没有使用的页面进行删除。
该算法主要通过页面结构中的访问时间来实现。
时间记录页面的最后访问时间。
因此,当需要删除一个页面时,选择时间值最小的页面,即最近最长时间没有使用的页面进行删除。
(4) LFU页面替换算法LFU要求每个页面配置一个计数器(即页面结构中的计数器)。
一旦页面被访问,计数器的值将增加1。
当需要替换一个页面时,将选择计数器值最小的页面,即存储器中访问次数最少的页面进行清除。
⑤NUR页面替换算法NUR要求为每个页面设置一个访问位(访问位仍然可以由页面结构中的计数器表示)。
当页面被访问时,其访问位计数器被设置为1。
当需要页面替换时,替换算法从替换指针(最初指向第一页)开始顺序检查内存中的每一页。
如果其访问位为0,则选择页面进行替换,否则,替换指针向下移动以继续向下搜索。
一目的与要求(1) 请求页式虚存管理是常用的虚拟存储管理方案之一。
(2) 通过请求页式虚存管理中对页面置换算法的模拟,加深理解虚拟存储技术的特点。
(3) 模拟页式虚拟存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断.二实验内容或题目(1)本实验要求使用C语言编程模拟一个拥有若干个虚页的进程在给定的若干个实页中运行、并在缺页中断发生时分别使用FIFO和LRU算法进行页面置换的情形。
(2)虚页的个数可以事先给定(例如10个),对这些虚页访问的页地址流(其长度可以事先给定,例如20次虚页访问)可以由程序随机产生,也可以事先保存在文件中。
(3)要求程序运行时屏幕能显示出置换过程中的状态信息并输出访问结束时的页面命中率。
(4)程序应允许通过为该进程分配不同的实页数,来比较两种置换算法的稳定性。
三实验步骤与源程序(1)实验步骤1、理解好相关实验说明。
2、根据实验说明,画出相应的程序流程图。
3、按照程序流程图,用C语言编程并实现。
(2)流程图如下:①虚页和实页结构在虚页结构中,pn代表虚页号,因为共10个虚页,所以pn的取值范围是0—9。
pfn代表实页号,当一虚页未装入实页时,此项值为-1;当该虚页已装入某一实页时,此项值为所装入的实页的实页号pfn。
time项在FIFO算法中不使用,在LRU中用来存放对该虚页的最近访问时间。
在实页结构中中,pn代表虚页号,表示pn所代表的虚页目前正放在此实页中。
pfn代表实页号,取值范围(0—n-1)由动态指派的实页数n所决定。
next是一个指向实页结构体的指针,用于多个实页以链表形式组织起来,关于实页链表的组织详见下面第4点。
②程序流程图如下:(3)源程序如下:#include<iostream.h>#define M 40int N;struct Pro{int num,time;};int Input(int m,Pro p[M]){cout<<"请输入实际页数:";do{cin>>m;if(m>M)cout<<"数目太多,请重试"<<endl;else break;}while(1);//cout<<"请输入各页面号:";for(int i=0;i<m;i++){cout<<"第"<<i<<"个页面号为:";cin>>p[i].num;p[i].time=0;}return m;}void print(Pro *page1)//打印当前的页面{Pro *page=new Pro[N];page=page1;for(int i=0;i<N;i++)cout<<page[i].num<<" ";cout<<endl;}int Search(int e,Pro *page1 ){Pro *page=new Pro[N];page=page1;for(int i=0;i<N;i++)if(e==page[i].num)return i; return -1;}int Max(Pro *page1){Pro *page=new Pro[N];page=page1;int e=page[0].time,i=0;while(i<N)//找出离现在时间最长的页面{if(e<page[i].time)e=page[i].time;i++;}for( i=0;i<N;i++)if(e==page[i].time)return i;return -1;}int Compfu(Pro *page1,int i,int t,Pro p[M]){Pro *page=new Pro[N];page=page1;int count=0;for(int j=i;j<M;j++){if(page[t].num==p[j].num )break;else count++;}return count;}int main(){cout<<"可用内存页面数:";cin>>N;Pro p[M];Pro *page=new Pro[N];char c;int m=0,t=0;float n=0;m=Input(m,p);do{for(int i=0;i<N;i++)//初试化页面基本情况{page[i].num=0;page[i].time=2-i;}i=0;cout<<"************************"<<endl;cout<<"*****f:FIFO页面置换*****"<<endl;cout<<"*****l:LRU页面置换******"<<endl;cout<<"*****o:OPT页面置换******"<<endl;cout<<"*****按其它键结束*******"<<endl;cout<<"************************"<<endl;cout<<"请选择操作类型(f,l,o):";cin>>c;if(c=='f')//FIFO页面置换{n=0;cout<<"页面置换情况: "<<endl;while(i<m){if(Search(p[i].num,page)>=0)i++;//找到相同的页面else{if(t==N)t=0;else{n++;//page[t].num=p[i].num;print(page);t++;}}}cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl; }if(c=='l')//LRU页面置换{ n=0;cout<<"页面置换情况: "<<endl;while(i<m){int k;k=t=Search(p[i].num,page);if(t>=0)page[t].time=0;else{n++;t=Max(page);page[t].num=p[i].num;page[t].time=0;}if(t==0){page[t+1].time++;page[t+2].time++;}if(t==1){page[2].time++;page[0].time++;}if(t==2){page[1].time++;page[0].time++;}if(k==-1) print(page); i++;}cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl;}if(c=='o')//OPT页面置换{n=0;while(i<m){if(Search(p[i].num,page)>=0)i++;else{int temp=0,cn;for(t=0;t<N;t++){if(temp<Compfu(page,i,t,p)){temp=Compfu(page,i,t,p); cn=t;}}page[cn]=p[i];n++;print(page);i++;}}cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl; }}while(c=='f'||c=='l'||c=='o');return 0;});四测试数据与实验结果五结果分析与实验体会通过上机,我了解了许多关于操作系统的专业知识。
操作系统上机实验报告实验名称:存储管理实验目的:通过请求页式存储管理页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理页面置换算法。
实验内容:1.设计一个虚拟存储区和内存工作区;例如内存工作区大小为9个内存块,假设系统中最多可运行3个进程,每个进程分配3个内存块;2.模拟实现FIFO、LRU、OPT算法,给出页面走向,可计算缺页率;3.根据实验结果比较几种算法的差别。
实验步骤及分析:(一)FIFO算法实现提示定义一个常量total_instruction来记录页面总共使用的次数;定义一个变量diseffect记录总共换入页面的次数。
利用公式diseffect/total_instruction*100%可以得到缺页率。
(1)初始化。
设置两个数组page[ap]和pagecontrol[pp]分别表示进程页面数和内存分配的页面数,并产生一个随机数序列pageorder[total_instruction ](这个序列由page[]的下标随机构成)表示待处理的进程页面顺序,diseffect置0。
(2)看pageorder[]中是否有下一个元素,若有,就由pageorder[]中获取该页面的下标,并转到(3);如果没有就转到(7)。
(3)如果该page已在内存中,就转到(2);否则就到(4),同时未命中的diseffect加1。
(4)观察pagecontrol是否占满,如果占满须将使用队列中最先进入的pagecontrol单元“清干净”,同时将对应的page[]单元置为“不在内存中”。
(5)将该page[]与pagecontrol[]建立关系。
可以改变pagecontrol[]的标志位,也可以采用指针链接,总之至少要使对应的pagecontrol单元包含两个信息:一是它被使用了,二是哪个page[]单元使用的。
Page[]单元也包含两个信息:对应的pagecontrol 单元号和本 page[]单元已在内存中。
____大学____学院实验报告课程名称:计算机操作系统实验名称:存储管理实验实验日期:班级:姓名:学号:仪器编号: 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。
欢迎共阅班级: 姓名: 学号: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、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。
操作系统实验报告一、实验题目:存储管理(该实验为综合性实验,共用8个学时)二、实验要求:1、通过随机数产生一个指令序列,共320条指令。
其地址按下述原则生成:①50%的指令是顺序执行的;②25%的指令是均匀分布在前地址部分;③25%的指令是均匀分布在后地址部分;具体的实施方法是:A.在[0,319]的指令地址之间随机选取一起点M;B.顺序执行一条指令,即执行地址为M+1的指令;C.在前地址[0,M+1]中随机选取一条指令并执行,该指令的地址为M’;D.顺序执行一条指令,其地址为M’+1;E.在后地址[M’+2,319]中随机选取一条指令并执行;F.重复A—E,直到执行320次指令。
2、指令序列变换成页地址流,设:①页面大小为1K;②用户内存容量为4页到32页;③用户虚存容量为32K。
在用户虚存中,按每页存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:第0条~第9条指令为第0页(对应虚存地址为[0,9]);第10条~第19条指令为第1页(对应虚存地址为[10,19]);…………第310条~第319条指令为第31页(对应虚存地址为[310,319]);3、计算并输出下述各种算法(可任选三个)在不同内存容量下的命中率。
A. FIFO先进先出置换算法;B. LRU最近最久未使用置换算法;C. OPT最佳置换算法。
D. NUR最近未使用置换算法。
E. LFU最少使用置换算法。
三、总的设计思想、环境语言、工具等总的设计思想:1、编写函数计算并输出下述各种算法的命中率①OPT页面置换算法OPT所选择被淘汰的页面是已调入内存,且在以后永不使用的,或是在最长时间内不再被访问的页面。
因此如何找出这样的页面是该算法的关键。
可为每个页面设置一个步长变量,其初值为一足够大的数,对于不在内存的页面,将其值重置为零,对于位于内存的页面,其值重置为当前访问页面与之后首次出现该页面时两者之间的距离,因此该值越大表示该页是在最长时间内不再被访问的页面,可以选择其作为换出页面。
操作系统存储管理实验报告一、实验目的操作系统的存储管理是计算机系统中非常重要的组成部分,它直接影响着系统的性能和资源利用率。
本次实验的目的在于深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握存储分配、回收、地址转换等关键技术,并对不同存储管理策略的性能进行分析和比较。
二、实验环境本次实验在 Windows 10 操作系统下进行,使用 Visual Studio 2019 作为编程环境,编程语言为 C++。
三、实验内容(一)固定分区存储管理1、原理固定分区存储管理将内存空间划分为若干个固定大小的分区,每个分区只能装入一道作业。
分区的大小可以相等,也可以不等。
2、实现创建一个固定大小的内存空间数组,模拟内存分区。
为每个分区设置状态标志(已分配或空闲),并实现作业的分配和回收算法。
3、实验结果与分析通过输入不同大小的作业请求,观察内存的分配和回收情况。
分析固定分区存储管理的优缺点,如内存利用率低、存在内部碎片等。
(二)可变分区存储管理1、原理可变分区存储管理根据作业的实际需求动态地划分内存空间,分区的大小和数量是可变的。
2、实现使用链表或数组来管理内存空间,记录每个分区的起始地址、大小和状态。
实现首次适应、最佳适应和最坏适应等分配算法,以及分区的合并和回收算法。
3、实验结果与分析比较不同分配算法的性能,如分配时间、内存利用率等。
观察内存碎片的产生和处理情况,分析可变分区存储管理的优缺点。
(三)页式存储管理1、原理页式存储管理将内存空间和作业都划分为固定大小的页,通过页表将逻辑地址转换为物理地址。
2、实现设计页表结构,实现逻辑地址到物理地址的转换算法。
模拟页面的调入和调出过程,处理缺页中断。
3、实验结果与分析测量页式存储管理的页面置换算法(如先进先出、最近最少使用等)的命中率,分析其对系统性能的影响。
探讨页大小的选择对存储管理的影响。
(四)段式存储管理1、原理段式存储管理将作业按照逻辑结构划分为若干个段,每个段有自己的名字和长度。
实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。
二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。
三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。
在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。
2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。
为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。
3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。
同样通过对空闲分区链表的排序和查找来实现。
(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。
在模拟过程中,使用一个队列来记录页面的进入顺序。
2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。
通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。
3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。
四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。
2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。
3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。
实验二存储管理2.1背景知识耗尽内存是Windows 2000/XP系统中最常见的问题之一。
当系统耗尽内存时,所有进程对内存的总需求超出了系统的物理内存总量。
随后,Windows 2000/XP必须借助它的虚拟内存来维持系统和进程的运行。
虚拟内存机制是Windows 2000/XP操作系统的重要组成部分,但它的速度比物理内存慢得多,因此,应该尽量避免耗尽物理内存资源,以免导致性能下降。
解决内存不足问题的一个有效的方法就是添加更多的内存。
但是,一旦提供了更多的内存,Windows 2000/XP很可以会立即“吞食”。
而事实上,添加更多的内存并非总是可行的,也可能只是推迟了实际问题的发生。
因此,应该相信,优化所拥有的内存是非常关键的。
1、分页过程当Windows 2000/XP求助于硬盘以获得虚拟内存时,这个过程被称为分页(paging)。
分页就是将信息从主内存移动到磁盘进行临时存储的过程。
应用程序将物理内存和虚拟内存视为一个独立的实体,甚至不知道Windows 2000/XP使用了两种内存方案,而认为系统拥有比实际内存更多的内存。
例如,系统的内存数量可能只有16MB,但每一个应用程序仍然认为有4GB内存可供使用。
使用分页方案带来了很多好处,不过这是有代价的。
当进程需要已经交换到硬盘上的代码或数据时,系统要将数据送回物理内存,并在必要时将其他信息传输到硬盘上,而硬盘与物理内存在性能上的差异极大。
例如,硬盘的访问时间通常大约为4-10毫秒,而物理内存的访问时间为60 us,甚至更快。
2、内存共享应用程序经常需要彼此通信和共享信息。
为了提供这种能力,Windows 2000/XP必须允许访问某些内存空间而不危及它和其他应用程序的安全性和完整性。
从性能的角度来看,共享内存的能力大大减少了应用程序使用的内存数量。
运行一个应用程序的多个副本时,每一个实例都可以使用相同的代码和数据,这意味着不必维护所加载应用程序代码的单独副本并使用相同的内存资源。
无论正在运行多少个应用程序实例,充分支持应用程序代码所需求的内存数量都相对保持不变。
3、未分页合并内存与分页合并内存Windows 2000/XP决定了系统内存组件哪些可以以及哪些不可以交换到磁盘上。
显然,不应该将某些代码 (例如内核) 交换出主内存。
因此,Windows 2000/XP将系统使用的内存进一步划分为未分页合并内存和分页合并内存。
分页合并内存是存储迟早需要的可分页代码或数据的内存部分。
虽然可以将分页合并内存中的任何系统进程交换到磁盘上,但是它临时存储在主内存的这一部分,以防系统立刻需要它。
在将系统进程交换到磁盘上之前,Windows 2000/XP会交换其他进程。
未分页合并内存包含必须驻留在内存中的占用代码或数据。
这种结构类似于早期的MS-DOS程序使用的结构,在MS-DOS中,相对较小的终止并驻留程序 (Terminate and Stay Resident,TSR) 在启动时加载到内存中。
这些程序在系统重新启动或关闭之前一直驻留在内存的特定部分中。
例如,防病毒程序将加载为TSR程序,以预防可能的病毒袭击。
未分页合并内存中包含的进程保留在主内存中,并且不能交换到磁盘上。
物理内存的这个部分用于内核模式操作(例如,驱动程序)和必须保留在主内存中才能有效工作的其他进程。
没有主内存的这个部分,内核组件就将是可分页的,系统本身就有变得不稳定的危险。
分配到未分页内存池的主内存数量取决于服务器拥有的物理内存数量以及进程对系统上的内存地空间的需求。
不过,Windows 2000/XP将未分页合并内存限制为256MB (在Windows NT 4中的限制为128MB) 。
根据系统中的物理内存数量,复杂的算法在启动时动态确定Windows 2000/XP系统上的未分页合并内存的最大数量。
Windows 2000/XP内部的这一自我调节机制可以根据当前的内存配置自动调整大小。
例如,如果增加或减少系统中的内存数量,那么Windows2000将自动调整未分页合并内存的大小,以反映这一更改。
4、提高分页性能只有一个物理硬盘驱动器的系统限制了优化分页性能的能力。
驱动器必须处理系统和应用程序的请求以及对分页文件的访问。
虽然物理驱动器可能有多个分区,但是将分页文件分布到多个分区的分页文件并不能提高硬盘驱动器的能力。
只有当一个分区没有足够的空间来包含整个分页文件时,才将分页文件放在同一个硬盘的多个分区上。
拥有多个物理驱动器的服务器可以使用多个分页文件来提高分页性能。
关键是将分页请求的负载分布到多个物理硬盘上。
实际上,使用独立物理驱动器上的分页文件,系统可以同时处理多个分页请求。
各个物理驱动器可以同时访问它自己的分页文件并写入信息,这将增加可以传输的信息量。
多个分页文件的最佳配置是将各个分页文件放在拥有自己的控制器的独立驱动器上。
不过,由于额外的费用并且系统上的可用中断很有限,因此对于大多数基于服务器的配置来说,这可能是不切实际的解决方案。
分页文件最重要的配置参数是大小。
无论系统中有多少个分页文件,如果它们的大小不合适,那么系统就可能遇到性能问题。
如果初始值太小,那么系统可能必须扩大分页文件,以补偿额外的分页活动。
当系统临时增加分页文件时,它必须在处理分页请求的同时创建新的空间。
这时,系统将出现大量的页面错误,甚至可能出现系统失效。
当系统必须在进程的工作区外部 (在物理内存或分页文件中的其他位置) 查找信息时,就会出现页面错误。
当系统缺乏存储资源(物理内存及虚拟内存)来满足使用需求,从而遇到过多的分页时,就会出现系统失效。
系统将花更多的时间来分页而不是执行应用程序。
当系统失效时,Memory:Pages/see计数器将持续高于每秒100页。
系统失效严重降低了系统的性能。
此外,动态扩展分页文件将导致碎片化。
分页文件将散布在整个磁盘上而不是在启动时的连续空间中创建,从而增加了系统的开销,并导致系统性能降低。
因此,应该尽量避免系统增加分页文件的大小。
提示:1) WINDOWS中采用的虚拟存储管理方案是请求页式存储管理,分页文件就是我们原理课中所说的交换/对换文件,存放的内容是暂时被交换到外存中的进程页面。
UNIX使用的是交换分区,WINDOWS使用的是交换文件。
2)在NTFS驱动器上,总是至少保留25%的空闲驱动器空间,以确保可以在连续的空间中创建分页文件。
3)Windows 2000使用内存数量的1.5倍作为分页文件的最小容量,这个最小容量的两倍作为最大容量。
它减少了系统因为错误配置的分页文件而崩溃的可能性。
系统在崩溃之后能够将内存转储写入磁盘,所以系统分区必须有一个至少等于物理内存数量加上1的分页文件。
5、Windows虚拟内存Windows 2000是32位的操作系统,它使计算机CPU可以用32位地址对32位内存块进行操作。
内存中的每一个字节都可以用一个32位的指针来寻址。
这样,最大的存储空间就是232字节或4000兆字节 (4GB) 。
这样,在Windows下运行的每一个应用程序都认为能独占可能的4GB大小的空间。
而另一方面,实际上没有几台机器的RAM能达到4GB,更不必说让每个进程都独享4GB内存了。
Windows在幕后将虚拟内存(virtual memory,VM) 地址映射到了各进程的物理内存地址上。
而所谓物理内存是指计算机的RAM和由Windows分配到用户驱动器根目录上的换页文件。
物理内存完全由系统管理。
在Windows 2000环境下,4GB的虚拟地址空间被划分成两个部分:低端2GB提供给进程使用,高端2GB提供给系统使用。
这意味着用户的应用程序代码,包括DLL以及进程使用的各种数据等,都装在用户进程地址空间内 (低端2GB) 。
用户进程的虚拟地址空间也被分成三部分:1)虚拟内存的已调配区 (committed) :具有备用的物理内存,根据该区域设定的访问权限,用户可以进行写、读或在其中执行程序等操作。
2)虚拟内存的保留区 (reserved) :没有备用的物理内存,但有一定的访问权限。
3)虚拟内存的自由区 (free) :不限定其用途,有相应的PAGE_NOACCESS权限。
与虚拟内存区相关的访问权限告知系统进程可在内存中进行何种类型的操作。
例如,用户不能在只有PAGE_READONLY权限的区域上进行写操作或执行程序;也不能在只有PAGE_EXECUTE权限的区域里进行读、写操作。
而具有PAGE_ NOACCESS权限的特殊区域,则意味着不允许进程对其地址进行任何操作。
在进程装入之前,整个虚拟内存的地址空间都被设置为只有PAGE_NOACCESS权限的自由区域。
当系统装入进程代码和数据后,才将内存地址的空间标记为已调配区或保留区,并将诸如EXECUTE、READWRITE和READONLY的权限与这些区域相关联。
程序清单2-1还显示了如何理解Virtual QueryEX() API填充的MEMORY_BASIC_INFORMATION结构,如表2-l所示。
此数据描述了进程虚拟内存空间中一组虚拟内存页面的当前状态。
其中State项表明这些区域是否为自由区、已调配区或保留区;Protect项则包含了Windows系统为这些区域添加了何种访问保护;Type项则表明这些区域是可执行图像、内存映射文件还是简单的私有内存。
VirtualQueryEX() API能让用户在指定的进程中,对虚拟内存地址的大小和属性进行检测。
表2-1 MEMORY_BASIC_INFORMATION结构的成员成员名称目的PVOID BaseAddress虚拟内存区域开始处的指针PVOID AllocationBase 如果这个特定的区域为子分配区的话,则为虚拟内存外面区域的指针;否则此值与BaseAddress相同DWORD AllocationProtect 虚拟内存最初分配区域的保护属性。
其可能值包括:PAGE_NOACCESS,PAGE_READONLY,PAGE_REA DWRITE和PAGE _EXECUTE_READDWORD RegionSize虚拟内存区域的字节数DWORD State 区域的当前分配状态。
其可能值为MEM_COMMIT,MEM_FREE和MEM_RESERVEDWORD Protect 虚拟内存当前区域的保护属性。
可能值与AllocationProtect成员的相同DWORD Type 虚拟内存区域中出现的页面类型。
可能值为MEM_IMAGE, MEM_MAPPED和MEM_PRIVATEWindows还提供了一整套能使用户精确控制应用程序的虚拟地址空间的虚拟内存API。
一些用于虚拟内存操作及检测的API见表4-2所示。