JAVA OS 虚拟存储器之请求分页存储管理基本框架

该代码实现了一个简单的虚拟内存管理系统,包括进程创建、按到达时间排序进程队列、执行进程等功能。在执行过程中,使用了LRU页面置换算法处理缺页情况,并维护了物理内存、访问频率、访问时间和入队顺序等数据结构。
摘要由CSDN通过智能技术生成

import java.util.*;

class VirMM {
    // 物理内存的总块数,假设为35
    private static final int TOTAL_BLOCKS = 1;

    private static final int MAX_PAGES = 1;
    private int[] memory;

    // 进程队列,用于存储所有创建的进程
    public Queue<PCB> processQueue;

    // 构造方法,初始化物理内存和进程队列
    public VirMM() {
        for(int i=0;i<5;i++)
            lru[i]=new LRU();
        this.memory = new int[TOTAL_BLOCKS]; // 创建物理内存数组
        Arrays.fill(this.memory, -1); // 将所有元素初始化为-1,表示空闲

        this.frequency = new int[TOTAL_BLOCKS]; // 创建访问频率数组
        Arrays.fill(this.frequency, 0); // 将所有元素初始化为0

        this.time = new long[TOTAL_BLOCKS]; // 创建访问时间数组
        Arrays.fill(this.time, 0); // 将所有元素初始化为0

        this.order = new int[TOTAL_BLOCKS]; // 创建入队顺序数组
        Arrays.fill(this.order, 0); // 将所有元素初始化为0

        this.processQueue = new LinkedList<>(); // 创建进程队列
    }

    // 创建进程,分配基本物理块,插入就绪队列
    public void createProcess(int pid, int pages, int arrivetime, int worktime) {
        PCB pcb = new PCB(pid, pages, arrivetime, worktime);
        //allocateBlocks(pcb);
        processQueue.add(pcb);
        System.out.println("进程" + pid + "已创建");
    }

    public void sortProcessQueueByArrivalTime() {
        List<PCB> tempList = new ArrayList<>(processQueue);
        //因为只能对列表进行排序,所以我们先转化形成列表,然后对列表进行排序,然后把列表的元素给队列
        Collections.sort(tempList, new Comparator<PCB>() {
            @Override
            public int compare(PCB pcb1, PCB pcb2) {
                return pcb1.getArrivetime() - pcb2.getArrivetime();
            }
        });

        processQueue.clear();
        processQueue.addAll(tempList);
    }
    public void executeProcessQueue() {
                      。。。。自己需要执行的。。。。
    }

 
    private int   [][] createPageTable(PCB pcb) {
        int[][] pageTable = new int[pcb.getPages()][2]; // 页表数组,每个项包含逻辑页号和对应的物理页框号

        for (int i = 0; i < pcb.getPages(); i++) {
            int logicalPage = i; // 逻辑页号
            int physicalBlock = pcb.getBlocks()[i]; // 物理页框号
            pageTable[i][0] = logicalPage; // 设置逻辑页号
            pageTable[i][1] = physicalBlock; // 设置物理页框号
        }

        return pageTable;
    }

    int t=0;
    // 选择进程调度并执行
    public void Execute() {

        if (processQueue.isEmpty()) {
            System.out.println("没有可执行的进程");
            return;
        }

        while (!processQueue.isEmpty()) {
            PCB currentProcess = processQueue.peek();
            currentProcess.setState(1); // 设置进程状态为运行
            System.out.println("进程" + currentProcess.getPid() + "开始执行");

            boolean isBlocked = false;

            while (!currentProcess.isFinished()) {
                int currentAddress = currentProcess.getCurrentAddress();
                int page = getPageNumber(currentAddress);
                int offset = getOffset(currentAddress);
                int block = currentProcess.getBlocks()[page];
                System.out.println("进程页号" + page + "物理块号" + block);

                if (block == -1) { // 如果当前页没有分配物理块,调用页面置换
                    System.out.println("进程" + currentProcess.getPid() + "被阻塞,执行下一个进程");
                    processQueue.offer(currentProcess); // 将被阻塞的进程重新加入队列末尾
                    pageFault(currentProcess, page);

                    block = currentProcess.getBlocks()[page];
                    isBlocked = true;
                    break;
                }
                lru[currentProcess .getPid()].pushlru(page);
                int physicalAddress = getPhysicalAddress(block, offset);
                System.out.println("进程" + currentProcess.getPid() + "访问逻辑地址" + currentAddress +
                        ",对应物理地址为" + physicalAddress);

                // 更新页面置换算法相关数据


                currentProcess.step(); // 更新地址
            }

            //    if (!isBlocked) {
            // currentProcess.setState(3); // 设置进程状态为结束
            //System.out.println("进程" + currentProcess.getPid() + "执行完毕");

            // 释放进程占用的物理块
            //releaseBlocks(currentProcess);

            // 从就绪队列中移除当前执行完毕的进程
            processQueue.poll();
        }
    }
    //}


    // 获取页号
    private int getPageNumber(int address) {
        return address >>> 10;
    }
    //逻辑地址是由进程生成的地址,而物理地址是实际映射到物理内存中的地址。逻辑地址空间通常被划分为固定大小的页(Page),而物理内存也被划分为相同大小的页框(Page Frame)。
    // 获取偏移量
    private int getOffset(int address) {
        return address & 0b1111111111;
    }//保留地址的低10位(二进制表示为10个1),并将其他位设置为0。这样做的目的是提取出地址的低10位,即偏移量部分。

    // 获取物理地址
    private int getPhysicalAddress(int block, int offset) {
        return (block << 10) | offset;
    }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值