java实现操作系统中的最佳置换Optimal算法

Java实现操作系统中的最佳置换Optimal算法攻略

算法介绍

最佳置换算法(Optimal)也称为理论最优算法。其思想是根据还未完成的进程未来的使用情况,计算出每一个进程在什么时候会访问页面,然后选择最长时间以后才用到的页面进行置换。

实现步骤

  1. 首先根据需要分配的内存大小,将所有的物理块置为空闲状态,并初始化所有页面的最近使用时间为正无穷大。
  2. 当一个新页面需要进入物理块时,检查空闲块,如果有则直接分配。如果没有空闲块,我们需要检查将要置换的页,选择预计最长时间未被使用的页进行置换。
  3. 遍历所有getPageList()页面,记录每个页面下一次的使用时间(找到下一个访问时间最大的页)。
  4. 比较每一页最近的下次使用时间,选择将距离下一次访问时间最远的页面进行替换,将其写入磁盘、更新页面表与页表即可。
  5. 重复上述步骤,直到完成所有的分配请求。

Java代码

import java.util.*;

class OptimalPageReplacement {

    private final List<Integer> getPageList() {
        // 内部页面列表,根据任务中定义方式生成
        return Arrays.asList(1, 2, 3, 2, 4, 5, 6, 7, 6, 8, 7, 8, 9, 7, 8, 9, 5, 4, 5, 4, 2);
    }

    private final void replacePages(int numFrames) {
        List<Integer> pageList = getPageList();
        List<Integer> frames = new ArrayList<>();
        Map<Integer, Integer> nextOccurrences = new HashMap<>();
        int pageFault = 0;
        for (int i = 0; i < numFrames; i++) {
            frames.add(-1);
        }
        for (int i = 0; i < pageList.size(); i++) {
            int currentPage = pageList.get(i);
            int frameIndex = frames.indexOf(currentPage);
            if (frameIndex != -1) {
                System.out.println("Request for page " + currentPage + " already found in Frame " + frameIndex);
                continue;
            }
            System.out.println("Request for page " + currentPage + " not found");
            if (frames.contains(-1)) {
                int emptyFrameIndex = frames.indexOf(-1);
                frames.set(emptyFrameIndex, currentPage);
                System.out.println("Page " + currentPage + " allocated to empty frame " + emptyFrameIndex);
                nextOccurrences.put(currentPage, getNextOccurrence(pageList, i));
                continue;
            }
            int replacement = getNextToReplace(frames, nextOccurrences);
            int replacedPageIndex = frames.indexOf(replacement);
            frames.set(replacedPageIndex, currentPage);
            nextOccurrences.put(currentPage, getNextOccurrence(pageList, i));
            System.out.println("Page " + replacement + " replaced with page " + currentPage + " in Frame " + replacedPageIndex);
            pageFault++;
        }
        System.out.println("Total Page Faults:" + pageFault);
    }

    private final int getNextOccurrence(List<Integer> pageList, int currentPageIndex) {
        for (int i = currentPageIndex + 1; i < pageList.size(); i++) {
            if (pageList.get(i) == currentPageIndex) {
                return i;
            }
        }
        return pageList.size() + 1;
    }

    private final int getNextToReplace(List<Integer> frames, Map<Integer, Integer> nextOccurrences) {
        int max = -1;
        int replace = -1;
        for (int i = 0; i < frames.size(); i++) {
            int currentPage = frames.get(i);
            if (!nextOccurrences.containsKey(currentPage)) {
                return i;
            } else {
                if (nextOccurrences.get(currentPage) > max) {
                    max = nextOccurrences.get(currentPage);
                    replace = i;
                }
            }
        }
        return replace;
    }

    public static void main(String[] args) {
        OptimalPageReplacement opr = new OptimalPageReplacement();
        opr.replacePages(3);
    }
}

示例说明

示例1

在这个示例中,CPU占用一个包含3个物理页面的系统。对于这类小系统,函数的执行顺序取决于输入的页请求序列。

  • 请求页1。在请求1时,物理块是空的。第一个页面被分配到物理块0。
  • 请求页2。在请求2时,物理块中没有空的物理块。在这种情况下,根据Optimal算法,算法分配被分配最长时间周期内没有使用的页面。在这种情况下,即使整个未来将使用的时间取决于请求码,但最佳可用的物理块是0。这意味着物理块1和2分别为1和2,从而执行相应的页面错误。
  • 请求页3。在请求3时,物理块0和1都包含了一个页面。但是页面3并不在主存中。在这种情况下,根据Optimal算法,算法为3分配被分配最长时间周期内没有使用的页面。在这种情况下,optimal算法将页面0和1中的任意一个页面替换为页面3。此时,选择可以替换的页面是0,因为在页面调用链中,最长的时间为7。
  • 请求页2。在请求2时,物理块1和2分别为1和2。因此,找到页面2,因此不需要将当前所需的任何页面替换掉。
  • 请求页4。在请求4时,页面4并不在主存中。此时的页面分配情况为(2,1,0)。在这种情况下,算法使用有最长使用时间的页面(在这种情况下,页面1的下一个访问将在9次调用后进行,而其他页面的下一个访问在5和8次之后)。此时,可以替换的页面是页面0或页面2。因为页面0有更长的时间或未使用,因此将页面4换掉,并将新的页面0放入物理块0中。
  • 请求5。请求5时,页面5不在物理块中。此时的页面分配情况为(4,1,5)。在这种情况下,根据Optimal算法,使用拥有最长时间段的页面分配,因为希望在页面请求依赖关系中尽可能长时间地放置当前要求。在这种情况下,页面1的下一个使用周期最长。这时可以替换的页面是页面0或页面2。因为页面0比页面2下一个使用时间更长(页2应该在6次访问以后),页面0被替换为页面5。因此,页面分配变成了(5, 1, 4)。
  • 请求页6。在请求6时,可以替换的页面是页面4或页面1。然而,因为页面1比页面4下一个使用时间长,因此页面1被替换为页面6。此时,物理块分配变成了(5, 6, 4)。

示例2

在这个示例中,CPU占用一个包含3个物理页面的系统。

  • 请求页3.页面调入位于物理块0。
  • 请求页2.页面调入位于物理块1。
  • 请求页4。页面调入位于物理块2。
  • 请求页6。发现所有物理块都已经分配出去了,根据Optimal算法,要查找下一个将要被使用的页,发现所有人将在未来无限的某个时刻被使用。按顺序每个页面都被标记以寻找将来访问的页面,在这个例子中,唯一不同的是一个页面标记解封期间是很近的,这个页面将会被换出物理块。页面4被替换为页面6,物理块分配变成(3, 2, 6)。
  • 请求页2。因为页面2已经在物理块中了,因此不需要置换。
  • 请求页4。因为页面4已经在物理块中了,因此不需要置换。
  • 请求页3。此时物理块内所有页面都已经被使用,需要选择一个最佳页面移除。需要整个页面序列来算法,以查找下一个每个页面将被访问的时间。由于所有页面都曾经出现过,所以算法无法从物理块中移除任何页面。

因此,总共有1个页面错误。

总结

Optimal算法是一种最佳的估计算法,旨在像未来一样分配对于所有物理/虚拟页面调用快照都最优。尽管在实际情况下无法预测所有请求,但它仍然作为理论原型被使用。由于它是一种最佳的算法,因此在实际情况下可能不太可能出现不同的结果。在一些情况下,其他算法例如LRU可能会提供更好的结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java实现操作系统中的最佳置换Optimal算法 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 详解Java利用深度优先遍历解决迷宫问题

    详解Java利用深度优先遍历解决迷宫问题 简介 在计算机科学中,深度优先遍历是一种用于遍历或搜索树或图的概念。深度优先遍历会先访问深度最大的节点(或者最右边的节点),然后回溯到该节点的父节点,并开始遍历它的另一个子节点。这个过程会一直持续到所有的节点都被访问为止。 用深度优先遍历算法解决迷宫问题可以思路简单易懂,代码编写也相对比较简单。 实现步骤 1. 定义…

    Java 2023年5月19日
    00
  • Java程序命令行参数用法总结

    Java程序命令行参数用法总结 Java程序启动时可以传递命令行参数,这些参数会被Java虚拟机解析并传递给main方法。在程序中可以通过args参数获取到传递的命令行参数。本文将介绍Java程序命令行参数的用法。 获取命令行参数 Java程序获取命令行参数非常简单,只需在main方法的参数列表中添加一个String数组类型的参数即可。例如: public …

    Java 2023年5月23日
    00
  • JavaWeb实现学生信息管理系统(2)

    “JavaWeb实现学生信息管理系统(2)”是一篇教程文章,旨在介绍如何使用JavaWeb技术实现学生信息管理系统。以下是该教程的完整攻略: 简介 在本教程的第一部分中,我们已经搭建好了项目的框架,包括所需的Java类和JSP页面。在本部分中,我们将添加更多的功能来实现完整的学生信息管理系统,并对代码进行相应的优化。 功能实现 添加学生信息 可以通过一个表单…

    Java 2023年5月24日
    00
  • 关于Java中的IO流总结(推荐)

    关于Java中的IO流总结(推荐) 概述 在Java中,IO(Input/Output)流是通常用于读取和写入数据的方式。在Java中的IO包提供了很多实现,包括了输入/输出流、文件读取和写入、网络数据传输等。IO流以字节流和字符流两种形式存在,对应到Java中分别为InputStream/OutputStream和Reader/Writer。 IO流的分类…

    Java 2023年5月26日
    00
  • Java GenericObjectPool 对象池化技术之SpringBoot sftp 连接池工具类详解

    Java GenericObjectPool 对象池化技术之SpringBoot sftp连连接池工具类详解 本文主要介绍Java GenericObjectPool 对象池化技术之SpringBoot sftp 连接池工具类的使用方法和具体实现。对象池是大量高性能、低延迟应用的一种基本设计方式,它可以将连接、线程等可重用的资源进行有效管理和复用,从而提高系…

    Java 2023年5月26日
    00
  • window.location和document.location的区别分析

    下面我将详细讲解一下“window.location和document.location的区别分析”的攻略。 标题 简介 window.location和document.location是JavaScript中的两个对象,它们都表示当前页面的URL地址。虽然它们的属性和方法非常相似,但它们之间是有一些区别的。 window.location和documen…

    Java 2023年6月15日
    00
  • Spring源码剖析之Spring处理循环依赖的问题

    下面就是关于“Spring源码剖析之Spring处理循环依赖的问题”的完整攻略。 标题:Spring源码剖析之Spring处理循环依赖的问题 什么是循环依赖? 循环依赖指的是在Spring容器初始化bean时,A对象依赖B对象,同时B对象又依赖A对象。这种情况下,Spring无法推断依赖关系,会抛出BeanCurrentlyInCreationExcepti…

    Java 2023年5月31日
    00
  • Spring populateBean属性赋值和自动注入

    Spring框架是一款高效的Java开发框架,其优秀的依赖注入机制使得程序员们可以更加快速和高效的进行开发。其中,populateBean属性赋值和自动注入是Spring框架中最为常见的两种方式,下面将对这两种方式进行详细的讲解。 1. populateBean属性赋值 populateBean属性赋值是Spring框架中最为常用的一种方式,其作用是将数据传…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部