操作系统 LFU:最不经常使用(最少次)淘汰算法(Least Frequently Used) 用JAVA高级语言模拟 详细注释

本文介绍了LeastFrequentlyUsed(LFU)淘汰算法的应用,通过模拟用户输入的页面访问顺序,动态管理内存中的存储区块,计算缺页率。程序演示了两种不同存储区块数下的页面调度过程。
摘要由CSDN通过智能技术生成

LFU:最不经常使用(最少次)淘汰算法(Least Frequently Used)。LFU是淘汰一段时间内,使用次数最少的页面。

package HomeWork_OS.LRU;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class LFU_os {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        System.out.print("请输入存储区块数: ");
        int userInput = sc.nextInt();
        int[] brickArr = new int[userInput]; //元素默认都为0

        int indexNum = 1;
        StringBuffer sb = new StringBuffer();
        System.out.println("请输入页号走向(输入0结束): ");
        while(userInput!= 0){
            System.out.print("页面序号" +indexNum + ": " );
            userInput = sc.nextInt();
            sb.append(userInput);
            indexNum++;
        }
        System.out.println("输入结束" +
                "\n置换情况如下: ");
//        System.out.println("sb = " + sb.toString());



        String str = sb.toString();
        char arr1[] = str.toCharArray();    //将用户输入转换成字符串数组
        //页面数组
        int[][] arr = new int[(arr1.length)][2];
//		System.out.println("arr1.length = " + arr1.length);
//		System.out.println("arr.length = " + arr.length);
//      System.out.println("打印arr1 " + Arrays.toString(arr1));
//		System.out.println("indexArr1 = " + indexArr1);

        double pageFaultRate;              //缺页率
        int pageNum = arr1.length - 1;      //总页面数
        int pageFaultCount = 0;         //缺页次数

        int pageIndex = 1;//页面序号
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (j == 0 ){   //二维数组第一项存页面序号
                    arr[i][j] = pageIndex++;
                }else{  //二维数组第二项存页号
                    arr[i][j] = Integer.parseInt(String.valueOf(arr1[i]));  //将字符串数组转换成整型数组,存入到二维数组每一行的第二项中
                }
            }
        }

        //打印页面数组
       /* System.out.println("打印页面数组:");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (j == 0 ){
                    System.out.print( "页面" + arr[i][j] + "  ");
                }else{
                    System.out.println(arr[i][j] );
                }
            }
        }*/

        //建立一个存储页面序号和已访问次数的Map集合
        //页号为key,访问次数为value
        Map<Integer,Integer> map = new HashMap<>();

        boolean flagPage;//false 表示元素不存在brickArr中,true 表示存在
        for (int k = 0; k < arr.length; k++) {   //遍历页面数组
            if (arr[k][1] == 0){ //遍历到最后一个元素0的时候退出循环
                break;
            }

            //查找该页面是否存在
            Integer getKey =  map.get(arr[k][1]);
            if (getKey == null){  //如果当前页面不存在map集合中,则添加到该集合中
                map.put(arr[k][1],1);
            }else { //如果当前页面在map集合中,则将其的值加一
                Integer value = map.remove(arr[k][1]) + 1;
                map.put(arr[k][1],value);
            }

            flagPage = false; //设立一个标志位标识存储区块数组中是否存在该元素
            for (int i = 0; i < brickArr.length; i++) {  //遍历存储区块数组
                if(brickArr[i] == 0){   //当存储区块数组中的元素为0时,表示为空,可以直接调入页面
                    brickArr[i] = arr[k][1];
                    pageFaultCount++;//缺页次数加一
                    flagPage = false;
                    System.out.println("发生缺页中断,但内存中有空闲区," + arr[k][1] +"号页面直接调入!");
                    break;
                }else if (brickArr[i] == arr[k][1]){    //如果存储区块数组中有该元素,则结束内循环,继续遍历页面数组中的下一个元素
                    flagPage = false;
                    System.out.println("内存中有" + arr[k][1] + "号页面,无须缺页中断!");
                    break;
                }else{  //如果存储区块数组中没有该元素,将标识位修改为true
                    flagPage = true;
                }
            }

            if (flagPage){
                pageFaultCount++;//缺页次数加一

                //找出最近最久未使用的页面替换出去
                //存储map中birckArr中的页面号和出现次数
                int[][] minCountPage = new int[brickArr.length][2];

                //遍历存储区块数组元素
                for (int i = 0; i < minCountPage.length; i++) {
                        Integer getValue = map.get(brickArr[i]);  //获取该map元素的值(页面出现的次数)
                        minCountPage[i][0] = brickArr[i];         //存入最少出现次数页面号
                        minCountPage[i][1] = getValue;            //存入最少出现次数页面次数
                }

                //获取出现次数最小的页面值和页面号
                //赋数组最后的数为默认最小值
                int minPageValue = minCountPage[0][1],minPageNumKey = minCountPage[0][0];
                for (int i = 1; i < minCountPage.length; i++) {
                    if (minPageValue > minCountPage[i][1]){
                        minPageValue = minCountPage[i][1];
                        minPageNumKey = minCountPage[i][0];//获取最小value的页面号
                    }
                }

                //获取存储区块数组中历史出现次数最少的页面,在存储区块数组中的索引
                int brickArrMinPageIndex = 0;
                for (int i = 1; i < brickArr.length; i++) {
                    if (brickArr[i] == minPageNumKey){
                        brickArrMinPageIndex = i;
                        break;
                    }
                }

                System.out.println("发生缺页中断,将" + brickArr[brickArrMinPageIndex] + "号页面调出," +
                        arr[k][1] + "号装入!");

                //存储区块数组中元素挪动替换
                for (int i = 0; i < brickArr.length; i++) {
                    //将当前要添加的页面放到存储区块数组最后
                    if (i == brickArr.length - 1){
                        brickArr[i] = arr[k][1];
                    }else if (i >= brickArrMinPageIndex){
                        brickArr[i] = brickArr[i + 1];
                    }else
                        continue;
                }
            }

            /*打印存储区块数数组*/
/*            System.out.print("打印brickArr:  ");
            for (int i : brickArr) {
                System.out.print(i + " ");
            }
            System.out.println();
            System.out.println("遍历map:");
            for (Integer key : map.keySet()) {
                Integer value = map.get(key);
                System.out.print ("key:" + key + " value: "+ value + "\n");
            }
            System.out.println();*/

        }

        pageFaultRate = (double)pageFaultCount / pageNum * 100;         //缺页率
        System.out.println("页号" + pageNum +
                "个,缺页中断" + pageFaultCount +
                "次,缺页率:" + String.format("%.4f",pageFaultRate) +
                "%");

    }
}


程序调试:

调试一:

请输入存储区块数:3

请输入页号走向(输入0结束):

页面序号1: 4

页面序号2: 3

页面序号3: 2

页面序号4: 1

页面序号5: 4

页面序号6: 3

页面序号7: 5

页面序号8: 4

页面序号9: 3

页面序号10: 2

页面序号11: 1

页面序号12: 5

页面序号13: 0

输入结束!

置换情况如下:

发生缺页中断,但内存中有空闲区,4号页面直接调入!400

发生缺页中断,但内存中有空闲区,3号页面直接调入!430

发生缺页中断,但内存中有空闲区,2号页面直接调入!432

发生缺页中断,将4号页面调出,1号装入!321

发生缺页中断,将3号页面调出,4号装入!214

发生缺页中断,将2号页面调出,3号装入!143

发生缺页中断,将1号页面调出,5号装入!435

内存中有4号页面,无须缺页中断!435

内存中有3号页面,无须缺页中断!435

发生缺页中断,将5号页面调出,2号装入!432

发生缺页中断,将4号页面调出,1号装入!321

发生缺页中断,将3号页面调出,5号装入!215

页号12个,缺页中断10次,缺页率:83.3333%

调试二:

请输入存储区块数:4

请输入页号走向(输入0结束):

页面序号1: 4

页面序号2: 3

页面序号3: 2

页面序号4: 1

页面序号5: 4

页面序号6: 3

页面序号7: 5

页面序号8: 4

页面序号9: 3

页面序号10: 2

页面序号11: 1

页面序号12: 5

页面序号13: 0

输入结束!

置换情况如下:

发生缺页中断,但内存中有空闲区,4号页面直接调入!

发生缺页中断,但内存中有空闲区,3号页面直接调入!

发生缺页中断,但内存中有空闲区,2号页面直接调入!

发生缺页中断,但内存中有空闲区,1号页面直接调入!

内存中有4号页面,无须缺页中断!

内存中有3号页面,无须缺页中断!

发生缺页中断,将2号页面调出,5号装入!

内存中有4号页面,无须缺页中断!

内存中有3号页面,无须缺页中断!

发生缺页中断,将3号页面调出,2号装入!

发生缺页中断,将5号页面调出,1号装入!

发生缺页中断,将4号页面调出,5号装入!

页号12个,缺页中断8次,缺页率:66.6667%

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值