请求调页存储管理方式的模拟

先看下题目要求:

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);
    }
}
原文地址:https://www.cnblogs.com/mercuryli/p/5033480.html