zoukankan      html  css  js  c++  java
  • 请求调页存储管理方式的模拟

    先看下题目要求:

    1实验目的

    通过对页面、页表、地址转换和页面置换过程的模拟,加深对请求调页系统的原理和实现过程的理解。

    2实验内容

    (1)假设每个页面中可存放10条指令,分配给一作业的内存块数为4。

    (2)模拟一作业的执行过程。该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。在模拟过程中,如果所访问的指令已经在内存中,则显示其物理地址,并转下一条指令。如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。如果4个内存块中均已装入该作业,则需进行页面置换。最后显示其物理地址,并转下一条指令。在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。

    (3)置换算法:请分别考虑OPT、FIFO和LRU算法。

    (4)作业中指令的访问次序按下述原则生成:

    •50%的指令是顺序执行的。

    •25%的指令是均匀分布在前地址部分。

    •25%的指令时均匀分布在后地址部分。

    3实验结果(给出编写的程序源代码和运行结果的截图)

    这个题目需要注意的是:

    该作业的320条指令是可以重复的。你需要一个随机出来这320条指令,将它们除以10就代表了将要调用的页,也就是0~31页。随着320指令的执行,会不停的调用这32页。

    因为有四个内存块,所以需要定义四个块来存放调用的页面

    package yeReplace;
    /*
     * 内存中的物理块
     */
    public class BLOCK {
        public int pageNum;     //页号
        public int accessed;    //页的访问字段,记录页有多久没有被访问,用于opt置换
        public BLOCK() {
            super();
        }
        public BLOCK(int pageNum, int accessed) {
            super();
            this.pageNum = pageNum;
            this.accessed = accessed;
        }
        @Override
        public String toString() {
            return "BLOCK [pageNum=" + pageNum + ", accessed=" + accessed + "]";
        }
    }

    这是主类

    package yeReplace;
    
    import java.io.BufferedReader;
    import java.io.FileFilter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class PageAPP {
        public static final int bSIZE = 4;
        static int pc;  //程序计数器,用来记录指令的序号
        static int n;     //缺页计数器,用来记录缺页的次数
        static int[] temp = new int[320];  //用来存放产生的320条随机数
        static BLOCK[] block;
        static int i;    //FIFO中选择的物理块
        
        //初始化
        public static void init() {
            block = new BLOCK[bSIZE];
            pc = n = 0;
            for (int i = 0; i < bSIZE; i++) {
                BLOCK aa = new BLOCK(-1,0);
                block[i] = aa;
            }
        }
        //查找物理块中是否有该页面
        public static int findExits(int page){
            for (int i = 0; i < bSIZE; i++) {
                if (block[i].pageNum == page) {  
                    return i;            //物理块中是否含有要调用的页curPage,如果有返回其位置i
                }
            }
            return -1;
        }
        //查找空闲物理块
        public static int findSpace() {
            for (int i = 0; i < bSIZE; i++) {
                if (block[i].pageNum == -1) {
                    return i;        //存在空闲物理块的话就返回它的位置
                }
            }    
            return -1;
        }
        //选择应予置换的页面
        public static int findPage(){
            int position = 0;
            for (int i = 1; i < bSIZE; i++) {
                if (block[i].accessed > block[i-1].accessed){
                    position = i;
                }
            }
            return position;
        }
        //显示
        public static void display(){
            for (int i = 0; i < bSIZE; i++) {
                if (block[i].pageNum!=-1) {
                    if (block[i].pageNum<10) {
                        System.out.print("0" + block[i].pageNum+ " ");
                    }else {
                        System.out.print(block[i].pageNum + " ");
                    }
                }
            }
            System.out.println("");
        }
        //产生的320条随机数,可以重复
        public static void suijishu() throws IOException{
            int flag = 0;
            pc= getInt();   //第一条数据是自己输入的
            System.out.println("按照要求产生的随机数:");
            for (int i = 0; i < 320; i++) {
                temp[i] = pc;
                int a = (int)(java.lang.Math.random()*320);
                if (flag%2==0) {    //50%几率顺序执行
                    pc = ++pc%320;
                }else if (flag == 1) {       //25%几率向下执行
                    pc = a%(pc-1);
                }else if (flag == 3) {        //25%几率向上执行
                    pc = pc+1+(a%(320-(pc+1)));
                }
                flag = ++flag%4;     //flag的取值为0、1、2、3
                
                if (temp[i]<10) {
                    System.out.print("00"+ temp[i] + " ");
                }else if (temp[i]<100) {
                    System.out.print("0" + temp[i] + " ");
                }else {
                    System.out.print(temp[i] + " ");
                }
                if (i % 10 == 0) {
                    System.out.println("");
                }
            }
            System.out.println("");
        }
    
        //显示调用的页面队列
        public static void pageString(){
            for (int i = 0; i < 320; i++) {
                int a = temp[i]/10;    //a代表页号,将temp中的指令转化为调用的页
                if (a<10) {
                    System.out.print("0"+a+"  ");
                }else {
                    System.out.print(a + "  ");
                }
                if ((i+1)%10 == 0) {
                    System.out.println("");
                }
            }
        }
        //OPT算法
        public static void OPT(){
            int exist,position,space;
            int curPage;
            for (int i = 0; i < 320; i++) {
                pc = temp[i];
                curPage = pc/10;           //调用的页
                exist = findExits(curPage);  
                if (exist == -1) {
                    space = findSpace();
                    if (space != -1) {  //存在空的物理块
                        block[space].pageNum = curPage;
                        display();
                        n = n+1;
                    }else {
                        //不存在空的物理块
                        for (int j = 0; j < bSIZE; j++) {
                            for (int j2 = i; j2 < 320; j2++) {
                                if (block[j].pageNum!=temp[j2]/10) {
                                    
                                    BLOCK mm = new BLOCK(block[j].pageNum,1000);
                                    block[j] = mm;
                                }else {
                                    BLOCK mm = new BLOCK(block[j].pageNum,j2);
                                    block[j] = mm;
                                    break;
                                }
                            }
                        }
                        position = findPage();
                        block[position] = new BLOCK(curPage, 0);
                        display();
                        n++;
                    }
                }
            }
            System.out.println("缺页次数:" + n);
            int answer = (n * 100)/320;
            System.out.println("缺页率:" + answer + "%");
        }
        //FIFO的选择页方法
        public static int findBlock(){
            if (i<bSIZE) {
                return i++;
            }else {
                i=0;
                return i++;
            }
        }
        //FIFO
        public static void FIFO(){
            int exist,position,space;
            int curPage;
            for (int i = 0; i < 320; i++) {
                pc = temp[i];
                curPage = pc/10;
                exist = findExits(curPage);
                if (exist == -1) {
                    space = findSpace();
                    if (space != -1) {  //存在空的物理块
                        block[space].pageNum = curPage;
                        display();
                        n = n+1;
                    }else {
                        //不存在空的物理块
                        position = findBlock();  //与RTO不同的地方
                        block[position] = new BLOCK(curPage, 0);  
                        display();
                        n++;
                    }
                }
            }
            System.out.println("缺页次数:" + n);
            int answer = (n * 100)/320;
            System.out.println("缺页率:" + answer + "%");
        }
        
        //主函数
        public static void main(String[] args) throws IOException{
            init();
            System.out.println("输入第一次执行的指令指令号(0~320):");
            suijishu();
            
            while(true){
                System.out.println("输入指令:");
                System.out.println("1.显示对应的调用序列:");
                System.out.println("2.退出");
                int choice = getInt();
                switch(choice){
                case 1:
                    System.out.println("对应的调用队列:");
                    pageString();
                    System.out.println("选择置换算法:");
                    System.out.println("1.最佳置换算法:");
                    System.out.println("2.先进先出算法:");
                    int choice2 = getInt();
                    switch (choice2) {
                    case 1:
                        System.out.println("最佳置换算法:");
                        System.out.println("==============");
                        OPT();
                        break;
                    case 2:
                        System.out.println("先进先出算法:");
                        System.out.println("==============");
                        FIFO();
                        break;
                    case 3:
                        System.exit(0);
                        break;
                    default:
                        break;
                    }
                break;
                case 2:
                    System.exit(0);
                    break;
                }
            }
        }
        
        //程序输入方法
        public static String getString() throws IOException{
            InputStreamReader in = new InputStreamReader(System.in);
            BufferedReader buff = new BufferedReader(in);
            String s = buff.readLine();
            return s;
        }
        
        public static int getInt() throws IOException {
            String s = getString();
            return Integer.parseInt(s);
        }
    }
  • 相关阅读:
    MarkDown语法
    AxureRP 序列号
    数据库选型相关
    linux 防火墙
    SpringMVC控制器方法参数传入的ModelMap 和Model类型有啥区别
    2017中国软件技术大会参会总结
    SpringMVC的Model ModeMap ModelAndView @ModelAttribute @SessionAttribute区分
    mybatis调用oracle存储过程 out游标类型参数 如何赋给java map
    mybatis 调用 oracle 存储过程 select into 无记录时NO_DATA_FOUND异常处理分析
    mybatis 调用oracle存储过程如何返回out参数值
  • 原文地址:https://www.cnblogs.com/mercuryli/p/5033480.html
Copyright © 2011-2022 走看看