页面置换算法最佳页面置换算法模拟JAVA实现

操作系统存储管理页面置换算法-----最佳页面置换算法模拟(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.

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是Java页面置换算法模拟实现: ```java import java.util.Scanner; public class PageReplacement { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入内存块大小:"); int blockSize = scanner.nextInt(); System.out.print("请输入页面序列长度:"); int sequenceLength = scanner.nextInt(); int[] sequence = new int[sequenceLength]; System.out.println("请输入页面序列:"); for (int i = 0; i < sequenceLength; i++) { sequence[i] = scanner.nextInt(); } System.out.println("请选择页面置换算法:"); System.out.println("1. 先进先出算法(FIFO)"); System.out.println("2. 最佳置换算法(OPT)"); System.out.println("3. 最近最久未使用算法(LRU)"); int algorithm = scanner.nextInt(); switch (algorithm) { case 1: fifo(blockSize, sequence); break; case 2: opt(blockSize, sequence); break; case 3: lru(blockSize, sequence); break; default: System.out.println("无效的算法选择!"); break; } } // 先进先出算法(FIFO) private static void fifo(int blockSize, int[] sequence) { int[] memory = new int[blockSize]; // 内存块 int pointer = 0; // 内存块指针 int missCount = 0; // 缺页计数器 for (int i = 0; i < sequence.length; i++) { int page = sequence[i]; // 判断页面是否已经在内存中 boolean isInMemory = false; for (int j = 0; j < blockSize; j++) { if (memory[j] == page) { isInMemory = true; break; } } // 页面未在内存中,需要进行页面置换 if (!isInMemory) { missCount++; memory[pointer] = page; pointer = (pointer + 1) % blockSize; } } System.out.println("FIFO算法缺页次数:" + missCount); } // 最佳置换算法(OPT) private static void opt(int blockSize, int[] sequence) { int[] memory = new int[blockSize]; // 内存块 int missCount = 0; // 缺页计数器 for (int i = 0; i < sequence.length; i++) { int page = sequence[i]; // 判断页面是否已经在内存中 boolean isInMemory = false; for (int j = 0; j < blockSize; j++) { if (memory[j] == page) { isInMemory = true; break; } } // 页面未在内存中,需要进行页面置换 if (!isInMemory) { missCount++; // 找到后面最长时间不使用的页面进行置换 int maxDistance = 0; int maxIndex = -1; for (int j = 0; j < blockSize; j++) { int pageInMemory = memory[j]; int distance = Integer.MAX_VALUE; // 计算页面距离下一次使用的距离 for (int k = i + 1; k < sequence.length; k++) { if (sequence[k] == pageInMemory) { distance = k - i; break; } } if (distance > maxDistance) { maxDistance = distance; maxIndex = j; } } memory[maxIndex] = page; } } System.out.println("OPT算法缺页次数:" + missCount); } // 最近最久未使用算法(LRU) private static void lru(int blockSize, int[] sequence) { int[] memory = new int[blockSize]; // 内存块 int[] counter = new int[blockSize]; // 计数器 int missCount = 0; // 缺页计数器 for (int i = 0; i < sequence.length; i++) { int page = sequence[i]; // 判断页面是否已经在内存中 boolean isInMemory = false; int indexInMemory = -1; for (int j = 0; j < blockSize; j++) { if (memory[j] == page) { isInMemory = true; indexInMemory = j; break; } } // 页面未在内存中,需要进行页面置换 if (!isInMemory) { missCount++; // 寻找最近最久未使用的页面进行置换 int minCounter = Integer.MAX_VALUE; int minIndex = -1; for (int j = 0; j < blockSize; j++) { if (counter[j] < minCounter) { minCounter = counter[j]; minIndex = j; } } memory[minIndex] = page; counter[minIndex] = 0; } else { counter[indexInMemory]++; } // 所有页面计数器加一 for (int j = 0; j < blockSize; j++) { counter[j]++; } } System.out.println("LRU算法缺页次数:" + missCount); } } ``` 在程序中,先让用户输入内存块大小、页面序列长度和页面序列,然后让用户选择页面置换算法,程序会根据用户的选择进行相应的页面置换操作,并输出缺页次数。其中,实现了三种页面置换算法:先进先出算法(FIFO)、最佳置换算法(OPT)和最近最久未使用算法(LRU)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值