实验一 操作系统的三种页面置换算法
原创作者:原创,在原创作者的基础上进行了改进,(最佳置换,原作者第十行应该是ProcessBlocks[flag][j] 第62行j参数取值不对 第64行temp参数错误),三种算法均已实现
实验目的
编程模拟实现存储器页面置换的常用算法,调试分析相关存储器管理程序,加深对存储器页面置换常用算法的理解和实现技巧
实验内容
1、 自定义存储器管理有关的数据结构;
2、 依据最佳置换算法(Optimal)、先进先出置换算法(FIFO)、最近最久未使用算法(LRU)原理,编写对应函数,模拟系统的存储器页面置换功能;
3、 为了更好地模拟和评价算法的性能,允许用户自行指定可用页块数并输入需访问的页面号序列;
4、 统计以上算法实际需要的总页面数、缺页中断次数以及它们的缺页率;
5、 比较/分析以上算法的置换性能,并作出自己的评价
实验步骤
定义变量
public class 页面置换算法 { private static int MaxPage_num = 100; private static int[] PageView = new int[MaxPage_num]; private static int[][] Blocks = new int[MaxPage_num][MaxPage_num]; private static int[] PageCount = new int[MaxPage_num];
private static int PageNum; private static int BlockNum;
private static int MissingPageNum; private static double MissingPageRate;
private static boolean found;
private static int j; private static int i; private static int k;
private static int NULL = -1;
public static void input() { Scanner sc = new Scanner(System.in); System.out.println("请输入页面个数"); PageNum = sc.nextInt(); System.out.println("请输入物理块个数"); BlockNum = sc.nextInt(); System.out.println("请输入页面访问顺序"); for (int i = 0; i < PageNum; i++) { PageView[i] = sc.nextInt(); } }
|
输出函数
public static void output() { System.out.print("访问页面:"); for (i = 0; i < PageNum; i++) { System.out.print(PageView[i] + " "); } System.out.println(); System.out.println("物理块"); for (int j = 0; j < BlockNum; j++) { for (int i = 0; i < PageNum; i++) { if (Blocks[i][j] == NULL) System.out.print(" "); else System.out.print(Blocks[i][j] + " "); } System.out.println(" "); } MissingPageRate = (double) MissingPageNum / PageNum; System.out.println(); System.out.println("总页面数" + PageNum + "缺页次数" + MissingPageNum + "缺页率" + MissingPageRate + "%"); }
|
初始化
public static void original() { for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { Blocks[i][j] = NULL; } } MissingPageNum = 1; }
|
先进先出
public static void FIFO() { original();
Blocks[0][0] = PageView[0]; int temp = 0, flag = 0; for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { if (PageView[i] == Blocks[flag][j]) { break; } }
if (j == BlockNum) { for (k = 0; k < BlockNum; k++) { if (Blocks[flag][k] == NULL) { break; } else { Blocks[i][k] = Blocks[flag][k]; } } temp++; temp = temp % BlockNum; Blocks[i][temp] = PageView[i]; MissingPageNum++; flag = i; } else { continue; } }
output(); }
|
最佳置换
public static void OPT() { original();
Blocks[0][0] = PageView[0]; int temp, flag = 0;
for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { if (PageView[i] == Blocks[flag][j]) { break; } } if (j != BlockNum) { continue; } for (k = 0; k < BlockNum; k++) { if (Blocks[flag][k] == NULL) { break; } else { Blocks[i][k] = Blocks[flag][k]; } } for (j = 0; j < BlockNum; j++) { if (Blocks[i][j] == NULL) { Blocks[i][j] = PageView[i]; MissingPageNum++; flag = i; break; } } if (j != BlockNum) { continue; }
temp = 0; for (j = 0; j < BlockNum; j++) { for (k = i + 1; k < PageNum; k++) { if (Blocks[i][j] == PageView[k]) { PageCount[j] = k; break; } } if (k == PageNum) { PageCount[j] = PageNum; } }
for(int a=1;a<BlockNum;a++) { if(PageCount[a]>PageCount[temp]) temp=a; }
Blocks[i][temp] = PageView[i]; MissingPageNum++; flag = i; } output(); }
|
最近最久未使用
public static void LRU() { original();
Blocks[0][0] = PageView[0]; PageCount[0] = 0; int temp = 0, flag = 0; for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { if (PageView[i] == Blocks[flag][j]) { PageCount[j] = i; break; } } if (j != BlockNum) continue;
for (k = 0; k < BlockNum; k++) { if (Blocks[flag][k] == NULL) { break; } else { Blocks[i][k] = Blocks[flag][k]; } } for (j = 0; j < BlockNum; j++) { if (Blocks[i][j] == NULL) { Blocks[i][j] = PageView[i]; PageCount[j] = i; MissingPageNum++; flag = i; break; } } if (j != BlockNum) { continue; } temp = 0; for (j = 0; j < BlockNum; j++) { if (PageCount[temp] > PageCount[j]) { temp = j; } } Blocks[i][temp] = PageView[i]; PageCount[temp] = i; MissingPageNum++; flag = i; } output(); }
|
主函数
public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { input(); System.out.println("1.先进先出 2.最佳置换算法 3.最近最久未使用 4.退出"); int c = sc.nextInt(); switch (c) { case 1: FIFO(); break; case 2: OPT(); break; case 3: LRU(); break; case 4: System.exit(0); default: System.out.println("输入错误 重新输入"); break; } } } }
|
完整代码
package 操作系统实验;
import java.util.Scanner;
public class 页面置换算法 { private static int MaxPage_num = 100; private static int[] PageView = new int[MaxPage_num]; private static int[][] Blocks = new int[MaxPage_num][MaxPage_num]; private static int[] PageCount = new int[MaxPage_num];
private static int PageNum; private static int BlockNum;
private static int MissingPageNum; private static double MissingPageRate;
private static boolean found;
private static int j; private static int i; private static int k;
private static int NULL = -1;
public static void input() { Scanner sc = new Scanner(System.in); System.out.println("请输入页面个数"); PageNum = sc.nextInt(); System.out.println("请输入物理块个数"); BlockNum = sc.nextInt(); System.out.println("请输入页面访问顺序"); for (int i = 0; i < PageNum; i++) { PageView[i] = sc.nextInt(); } }
public static void output() { System.out.print("访问页面:"); for (i = 0; i < PageNum; i++) { System.out.print(PageView[i] + " "); } System.out.println(); System.out.println("物理块"); for (int j = 0; j < BlockNum; j++) { for (int i = 0; i < PageNum; i++) { if (Blocks[i][j] == NULL) System.out.print(" "); else System.out.print(Blocks[i][j] + " "); } System.out.println(" "); } MissingPageRate = (double) MissingPageNum / PageNum; System.out.println(); System.out.println("总页面数" + PageNum + "缺页次数" + MissingPageNum + "缺页率" + MissingPageRate + "%"); }
public static void original() { for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { Blocks[i][j] = NULL; } } MissingPageNum = 1; }
public static void FIFO() { original();
Blocks[0][0] = PageView[0]; int temp = 0, flag = 0; for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { if (PageView[i] == Blocks[flag][j]) { break; } }
if (j == BlockNum) { for (k = 0; k < BlockNum; k++) { if (Blocks[flag][k] == NULL) { break; } else { Blocks[i][k] = Blocks[flag][k]; } } temp++; temp = temp % BlockNum; Blocks[i][temp] = PageView[i]; MissingPageNum++; flag = i; } else { continue; } }
output(); }
public static void OPT() { original();
Blocks[0][0] = PageView[0]; int temp, flag = 0;
for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { if (PageView[i] == Blocks[flag][j]) { break; } } if (j != BlockNum) { continue; } for (k = 0; k < BlockNum; k++) { if (Blocks[flag][k] == NULL) { break; } else { Blocks[i][k] = Blocks[flag][k]; } } for (j = 0; j < BlockNum; j++) { if (Blocks[i][j] == NULL) { Blocks[i][j] = PageView[i]; MissingPageNum++; flag = i; break; } } if (j != BlockNum) { continue; }
temp = 0; for (j = 0; j < BlockNum; j++) { for (k = i + 1; k < PageNum; k++) { if (Blocks[i][j] == PageView[k]) { PageCount[j] = k; break; } } if (k == PageNum) { PageCount[j] = PageNum; } }
for(int a=1;a<BlockNum;a++) { if(PageCount[a]>PageCount[temp]) temp=a; }
Blocks[i][temp] = PageView[i]; MissingPageNum++; flag = i; } output(); }
public static void LRU() { original();
Blocks[0][0] = PageView[0]; PageCount[0] = 0; int temp = 0, flag = 0; for (i = 0; i < PageNum; i++) { for (j = 0; j < BlockNum; j++) { if (PageView[i] == Blocks[flag][j]) { PageCount[j] = i; break; } } if (j != BlockNum) continue;
for (k = 0; k < BlockNum; k++) { if (Blocks[flag][k] == NULL) { break; } else { Blocks[i][k] = Blocks[flag][k]; } } for (j = 0; j < BlockNum; j++) { if (Blocks[i][j] == NULL) { Blocks[i][j] = PageView[i]; PageCount[j] = i; MissingPageNum++; flag = i; break; } } if (j != BlockNum) { continue; } temp = 0; for (j = 0; j < BlockNum; j++) { if (PageCount[temp] > PageCount[j]) { temp = j; } } Blocks[i][temp] = PageView[i]; PageCount[temp] = i; MissingPageNum++; flag = i;
} output(); }
public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { input(); System.out.println("1.先进先出 2.最佳置换算法 3.最近最久未使用 4.退出"); int c = sc.nextInt(); switch (c) { case 1: FIFO(); break; case 2: OPT(); break; case 3: LRU(); break; case 4: System.exit(0); default: System.out.println("输入错误 重新输入"); break; } } }
}
|
运行结果


总结
通过页面置换算法程序的编写,最后三次相同物理块与访问次序输出比较,最佳置换算法选择以后永不使用的页面,以便保证最低的缺页率。先进先出算法在分配更多的物理块时反而会造成更高的缺页率。最近最久未使用算法,性能更好