实验2:页面置换模拟程序设计
一、实验目的
1.对页面置换做进一步的理解。
2.了解页面置换的任务。
3.通过编程掌握页面置换算法及缺页率计算。
4.了解Belady现象和抖动现象。
二、实验内容及实验要求
1.输入给出一组页面访问顺序(如页面走向是1、2、5、7、5、7、1、4、3、5、6、4、3、2、1、5、2)。
2.分配给该作业一定的物理块(如3块、4块等)(输入)。
3.分别利用OPT、FIFO、LRU页面置换算法模拟页面置换过程并输出换进和换出的页面号。
4.计算每种面置换算法缺页率并输出。
5.通过多次运行获得的结果进行比对,并对比对结果进行说明。
三、实验时间
4个学时
四、实验报告
1.程序中使用的数据结构及符号说明。
2.主要算法的流程图。
3.程序运行时的初值和运行结果截图。
4.通过测试数据观察并说明Belady现象。
5.程序清单并附上注释。
实验名称 页面置换模拟程序设计 实验地点 8教-323
sim.java
import java.util.Scanner;
class imitate {
int blockNum;//物理块数
int[]a;//页号数组
int[]b=new int[10];//块内数组
char[]que=new char[100];//缺页数组
int [][]table=new int[100][10];//显示矩阵
int count;//缺页次数
int k;
/* FIFO页面置换算法 */
void FIFO(){
count=0;
int acount=0;
for(int i=0;i<blockNum;i++){
b[i]=-1; //初始内存块中默认为空,用-1表示
}
for(int i=0;i<que.length;i++){
que[i]='N';
}
for(int i=0;i<a.length;i++){
k=0;
if(acount==blockNum){
acount=0;
}
if(i<blockNum) //访问的前几个页面,不在内存块中
{
b[i] = a[i];
for (int j = 0; j < blockNum; j++){
table[i][j] = b[j];
}
que[i] = 'Y';
count++;
}else
{//判断新页面号是否在物理块中
for(int j=0;j<blockNum;j++)
{
if(b[j]!=a[i])
k++;
else
{ //新页面在内存块中
for(int n=0;n<blockNum;n++){
table[i][n]=b[n];
}
}
}
if(k==blockNum) /*新页面不在物理块中,缺页*/
{
que[i]='Y';
count++;
/*内存块已满,需采用FIFO置换算法选择换出页*/
b[acount]=a[i];
acount++;
for(int n=0;n<blockNum;n++){
table[i][n]=b[n];
}
}
}
}
}
/* LRU页面置换算法 */
void LRU(){
count=0;
int []time=new int[100];
for(int i=0;i<blockNum;i++){
b[i]=-1; //初始内存块中默认为空,用-1表示
}
for(int i=0;i<que.length;i++){
que[i]='N';
}
for(int i=0;i<a.length;i++){
k=0;
if(i<blockNum) //访问的前几个页面,不在内存块中
{
b[i] = a[i];
time[i]=i;
for (int j = 0; j < blockNum; j++){
table[i][j] = b[j];
}
que[i] = 'Y';
count++;
}else
{//判断新页面号是否在物理块中
for(int j=0;j<blockNum;j++)
{
if(b[j]!=a[i])
k++;
else
{ //新页面在内存块中
time[j]=i;
for(int n=0;n<blockNum;n++){
table[i][n]=b[n];
}
}
}
if(k==blockNum) //新页面不在物理块中,缺页
{
que[i]='Y';
count++;
//内存块已满,需采用LRU置换算法选择换出页
int min=0;
for(int m=1;m<blockNum;m++)
if(time[m]<time[min]){
min=m;
}
b[min]=a[i];
time[min]=i;
for(int n=0;n<blockNum;n++){
table[i][n]=b[n];
}
}
}
}
}
/* OPT页面置换算法 */
void OPT(){
int []acount=new int[blockNum];//页号在内存块中的时长数组
int []q=new int[blockNum];
count=0;
for(int i=0;i<blockNum;i++){
acount[i]=0;
}
for(int i=0;i<blockNum;i++){
b[i]=-1; //初始内存块中默认为空,用-1表示
}
for(int i=0;i<que.length;i++){
que[i]='N';
}
for(int i=0;i<a.length;i++){
k=0;
if(i<blockNum) //访问的前几个页面,不在内存块中
{
b[i] = a[i];
for (int j = 0; j < blockNum; j++){
table[i][j] = b[j];
}
que[i] = 'Y';
count++;
}else
{//判断新页面号是否在物理块中
for(int j=0;j<blockNum;j++)
{
if(b[j]!=a[i])
k++;
else
{ //新页面在内存块中
acount[j]++;
for(int n=0;n<blockNum;n++){
table[i][n]=b[n];
}
}
}
if(k==blockNum) /*新页面不在物理块中,缺页*/
{
que[i]='Y';
count++;
/*内存块已满,需采用OPT置换算法选择换出页*/
int te=1;
for(int m=0;m<blockNum;m++){q[m]=0;}
for(int r=i+1;r<a.length;r++){
for(int m=0;m<blockNum;m++){
if(a[r]==b[m]){
q[m]=1;
te++;
if(te==blockNum){
for(int z=0;z<blockNum;z++){if(q[z]==0){b[z]=a[i];}}
for(int n=0;n<blockNum;n++){table[i][n]=b[n];}
}
}
}
}
}
}
}
}
//输入
void input(){
System.out.println("请输入一组页号:(页号间以空格隔开)");
Scanner s = new Scanner(System.in);
String inputStr = s.nextLine();
String[] strArray = inputStr.split(" ");
a = new int[strArray.length];
for(int i = 0 ; i < a.length ; i++){
a[i] = Integer.parseInt(strArray[i]);
}
System.out.println("请入物理块数:");
blockNum=s.nextInt();
}
//输出
void output(String t){
System.out.println("采用"+t+"页面置换算法结果如下:");
System.out.println();
System.out.print("页号:");
for(int i=0;i<a.length;i++){
System.out.printf("%3d",a[i]);
}
System.out.println();
System.out.println("-----------------------------------------------------");
for(int i=0;i<blockNum;i++)
{
System.out.printf("块%2d:",i);
for(int j=0;j<a.length;j++){
System.out.printf("%3d",table[j][i]);
}
System.out.println();
}
System.out.println("-----------------------------------------------------");
System.out.print("缺页:");
for(int i=0;i<a.length;i++){
System.out.printf("%3c",que[i]);
}
System.out.println();
System.out.println("-----------------------------------------------------");
System.out.printf("缺页次数:%d\n",count);
System.out.printf("缺页率:%.2f\n",(float)count/(float) a.length);
System.out.println("-----------------------------------------------------");
}
}
test.java
public class test {
//测试页号顺序:1 2 5 7 5 7 1 4 3 5 6 4 3 2 1 5 2
public static void main(String [] arg){
imitate imit=new imitate();
imit.input();
imit.FIFO();
imit.output("FIFO");
imit.LRU();
imit.output("LRU");
imit.OPT();
imit.output("OPT");
}
}
实验截图
截图在下文
报告
实验类型 设计 实验学时 4 实验日期 2021/X/X
★【注意】文档各种格式已经设置好并不得更改,填入内容即可
一、实验目的
1.对页面置换做进一步的理解。
2.了解页面置换的任务。
3.通过编程掌握页面置换算法及缺页率计算。
4.了解Belady现象和抖动现象。
二、实验内容
1.实验任务
(1)输入给出一组页面访问顺序(如页面走向是1、2、5、7、5、7、1、4、3、5、6、4、3、2、1、5、2)。
(2)分配给该作业一定的物理块(如3块、4块等)(输入)。
(3)分别利用OPT、FIFO、LRU页面置换算法模拟页面置换过程并输出换进和换出的页面号。
(4)计算每种面置换算法缺页率并输出。
(5)通过多次运行获得的结果进行比对,并对比对结果进行说明。
2.算法与程序设计
1)数据结构说明
int blockNum;//物理块数
int[]a;//页号数组
int[]b=new int[10];//块内数组
char[]que=new char[100];//缺页数组
int [][]table=new int[100][10];//显示矩阵
int count;//缺页次数
以一个一维数组int[]a存放顺序访问的页号,int[]b存放块内页号,int blockNum是模拟的物理块个数,最后二维数组table[]输出结果
2)数据输入(输入哪些数据、个数、类型、来源、输入方式)
键盘键入:blockNum,int[]a
物理块的数据输入由FIFO(),URL(),OPT()方法从页号数组中输入
3)数据处理(正确绘制流程图,说明数据处理步骤)
4)数据输出(程序运行结果截图。图幅大小适当,能看清楚的情况下尽量小)
3.实验小结
通过这次实验,自己见证了Belady现象和抖动现象,Belady现象,是指采用页面置换FIFO算法时,如果对一个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多,但缺页率反而提高的异常现象。因为FIFO页面置换,只管先进先出,性能较差,调出的页面可能是经常要访问的页面,当调出的页面经常需要访问时,就会出现Belady现象。Thrashing抖动现象,又叫颠簸。如果分配给进程的存储块数量小于进程所需要的最小值,进程的运行将很频繁地产生缺页中断,这种频率非常高的页面置换现象称为抖动。
结合到实际编码,我对FIFO,LRU,OPT这三种页面置换算法有了更加深刻的理解,FIFO算法,先进入内存的页,先被换出。FIFO页面置换算法实现简单,要求的硬件支持较少。但是性能并不很好,效率不高;存在Belady异常现象。
OPT算法,调入页置换出最久不会使用的得页,可以保证有最小缺页率。但是很难实现。
LRU算法,当需要置换一页时,移出在最近一段时间里最久没有使用过的页,以过去预测未来,效率高,实现比较简单。
三、实验环境
1.操作系统:WINDOWS10
2.开发工具:IntelliJ IDEA 2021.2.2
3.实验设备:PC