操作系统存储管理页面置换算法-----最佳页面置换算法模拟(JAVA实现)
话不多说,我们直接展示
package com.company;
import java.util.Arrays;
/**
* @Auther: Bender
* @Date: 2021/11/14 - 16:57
* @Description: com.company
* @version: 1.0
*/
//注释掉的是第一次做的程序,考虑不充分失败了
public class MyAlg {
public static boolean isIn(int a, int[] arr) { //判断某个数是否在数组中,返回true或者false
for(int i: arr){
if(a==i){
return true;
}
}
return false;
}
public static int isIn(int[] arr, int a) { //isIn方法重载,返回相等元素的数组下标,没有则返回下标
for(int i=0; i<arr.length; i++){
if(arr[i] == a)
return i;
}
return -1;
}
public static void optAdd(int[] contain, int[]list, int k) { //最佳置换算法的缺页处理(前提:内存区已满)
/*分析:应该分为多种情况,******需要注意的是当作业队列中出现多次已经存在内存中的作业时(例子:内存区[5,6,7] 作业队列[1,6,7,6]),我们只取第一个******
1.当后续作业队列中没有找到内存中已有的作业时
例子:内存区[6,7,8] 作业队列[1,2,3,4,5]
处理方式:默认替换0号元素
2.当后续作业队列中找到一个已经在内存中存在的作业时
例子:内存区[1,2,3] 作业队列[5,6,7,1,8]
处理方式:从0号元素开始,将未在作业队列中的元素依次替换
3、当后续作业队列中找到两个已经在内存中存在的作业时
例子:内存区[5,6,7] 作业队列[8,5,6]
处理方式:直接替换掉未出现的元素
4.当后续作业队列中找到内存区所有元素
例子:内存区[5,6,7] 作业队列[8,5,6,7]
处理方式:替换掉最后出现的元素
*/
int[] index = {-3,-3,-3}; //要返回的下标队列,选取其中最小的值作为第k个元素要替换的下标******
int inum = 3; //给index中的元素复制,随着赋值次数递减,最小的就是要替换的
int goalindex = 0;
for(int i=k+1; i<list.length; i++){ //从k的下一个元素开始遍历,原因:第K个元素调用此方法的前提是这个元素并不在内存中
if(isIn(list[i],contain)){ //该元素在内存中
int num = isIn(contain,list[i]); //返回相同的元素下标
if(index[num]==-3) //确保只取第一次,后续忽略
index[num] = inum--;
}
}
if(index[0]<0 && index[1]<0 && index[2]<0 ){ //情况一:默认替换第0个元素
index[0] = -4;
}
int temp = index[0];
for(int i=1; i<index.length; i++){ //找出index中的最小值
if(index[i]<temp) {
temp = index[i];
goalindex = i;
}
}
contain[goalindex] = list[k];
System.out.println("缺页中断"+ Arrays.toString(contain));
}
public static void opt(int[] list) {
System.out.println("-----这是最佳页面置换算法-----");
int times = 0; //记录缺页率
int[] contain = new int[3]; //模拟内存空间,大小为3
int isempty = 0; //对contain模拟内存中的元素进行计数
/*此循环的作用:将contain模拟内存装满
*/
int i; //在循环体外定义循环变量i是为了当循环结束时返回i的值(当内存区满后,对作业队列的执行从i+1开始)
for(i=0; i<list.length; i++) {
if(!isIn(list[i],contain)){ //当要放入的元素不在内存区中
contain[isempty] = list[i];
isempty++; //内存区元素加一
System.out.println("缺页中断"+Arrays.toString(contain));
times++;
if(isempty==3) { //当内存区的元素个数为3(内存区已满的情况)即可跳出此循环
break;
}
}//当要访问的元素在内存区已经存在时,我们不做任何操作
}
//执行至此处内存区已满,下面对作业队列遍历,缺页时执行页面置换操作,不缺页时不做任何操作
//具体的页面置换我希望单独设计成一个方法(前提:内存区此时已满,不达成这个前提,程序设计会复杂的多)
for(++i; i<list.length; i++){ //从上一个循环的下一个位置开始遍历作业队列
if(!isIn(list[i],contain)){ //缺页时的操作
optAdd(contain,list,i);
times++;
}//不缺页不执行任何操作
}
System.out.println("缺页次数:" + times + ",缺页中断率:" + (float)times / list.length);
}
// public static int search(int[] contain, int[] arr, int index){ //返回在之后的作业队列中,内存中最后一个被访问的内存块的下标
// int renum = 0; //最后该方法的返回值,指明要替换的主存块
// for(int i=index; i<arr.length; i++){ //对之后的作业队列进行遍历
// int num = isIn(contain,arr[i]);
// if(num!=-1)
// renum = num;
// }
// return renum;
// }
// public static void opt(int[] arr) {
// System.out.println("-----这是最佳置换算法-----");
// System.out.println("作业队列:"+Arrays.toString(arr));
// int times = 0; //用于记录置换次数(缺页中断次数),计算缺页率
// int elements = 0; //记录内存中的作业数
// int[] contain = new int[3]; //模拟主存空间
for(int i=0; i<3; i++){ //三个作业装入,现在主存装满
contain[i] = arr[i];
}
// contain[0] = arr[0]; //先将第一个作业放入内存
// times++; //缺页中断次数加一
// elements++; //内存作业数加一,变为1
// System.out.println("主存块:"+Arrays.toString(contain));
// for(int i=1; i<arr.length; i++){ //遍历作业队列
// if(!isIn(arr[i],contain)){ //当要访问的作业不在主存时
// times++; //缺页终断率加一
// if(elements>=3){ //内存已满
int index = search(contain,arr,i);
contain[index] = arr[i];
// System.out.println("中断:"+times+"次,"+Arrays.toString(contain)); //打印置换后的内存情况
// }else{ //内存未满,直接加如内存
// contain[elements] = arr[i];
// elements++;
// }
// }else{ //当要访问的作业就在内存时,将被访问的作业调至最后,其他作业依次向前移,因为当后续作业队列中的作业都不在主存时,默认替换主存数组的第0个元素(即距离上次调用的时间最长)
// if(elements>=3){ //内存区已满的情况
// int index = isIn(contain,arr[i]);
// if(index==1){
// int temp = contain[1];
// contain[1] = contain[2];
// contain[2] = temp;
// }else if(index == 0){
// int temp = contain[0];
// contain[0] = contain[1];
// contain[1] = contain[2];
// contain[2] = temp;
// }
// System.out.println("未发生中断"+Arrays.toString(contain));
// }
// }
// System.out.println("主存块:"+Arrays.toString(contain));
//
// }
//
// }
public static void main(String[] args) {
int[] arr = {6,7,6,5,9,6,8,9,7,6,9,6};
opt(arr);
}
}
运行结果的展示:
看了这篇页面置换算法的文章,试运行了一下发现错误很多,很多点没有考虑到,所以自己重写了一下
链接: https://blog.csdn.net/TianXiaobie/article/details/110451353?utm_source=app&app_version=4.18.0&code=app_1562916241&uLinkId=usr1mkqgl919blen.