OPT算法
定义:OPT(最佳置换算法):从主存中移出永远不再需要的页面,如果没有这样的页面存在,那就选择最长时间不需要访问的页面,来保证最低的缺页率。
import java.util.*;
public class OPT {
private static List<Integer> new_list = new ArrayList<Integer>();//定义一个缓存容器,备用
private static int temp = 0;//定义每次置换时需要替换的元素序列号
public void O(int[] seq,int pages) {
int page_break = 0;//定义断页次数
LinkedList<Integer> list = new LinkedList<Integer>();//定义一个缓存容器
for (int i = 0; i < seq.length; i++) {
if (!list.contains(seq[i])) {//如果list不包含访问序列需要访问的序列号时,包含则跳过
if (list.size() != pages) {//当物理块未满时
list.addLast(seq[i]);//追加到此列表的末尾
page_break++;//断页加一
}else {//如果物理块满了
int flag = list.indexOf(index(seq,list,i));//此返回值为需要替换的序列号
list.remove(flag);//删除这个元素
list.addLast(seq[i]);// 追加最后一个新元素
page_break++;// 置换,断页加一
}
}
}
//输出结果
System.out.println("断页次数:" + page_break + "\n断页中断率:" + page_break * 1.0 / seq.length);
}
//此方法主要是寻找需要替换的序列号,参数分别表示为访问序列号,物理块所装的序列号,当前要访问的序列号
//temp和new_list均为静态变量,因为在进行下一次的调用时,上一次的值会保留下来,这样有利于比较值的大小
public static int index(int[] seq, LinkedList<Integer> list, int num) {
int value=0;//定义返回值
//该for循环主要是添加当前访问序列之后的所有序列号,每次调用该方法,前一次的数据会被清空,再添加相应的元素
for (int j = num + 1; j < seq.length; j++) {
new_list.add(seq[j]);
}
//对物理块中的数据进行for循环
for (int k = 0; k < list.size(); k++) {
if (new_list.indexOf(list.get(k)) != -1) {//如果能在当前序列号之后的元素中找到相应的的元素
int flag = new_list.indexOf(list.get(k));//用flag记下它的下标
if(temp<flag) {//如果temp小于flag,则表明它离当前访问序列号越远,也就是要被淘汰的,赋值给temp
temp=flag;
}
if(k==list.size()-1) {//如果到末尾了,将最后所比的值赋值给value
value=new_list.get(temp);
}
}else {//如果不能在当前序列号之后的元素中找到相应的的元素
value=list.get(k);//直接获得需要替换的值
temp=0;//令temp=0;恢复初始值
new_list.clear();//清空new_list,恢复初始值
return value;
}
}
new_list.clear();//清空new_list,恢复初始值
temp=0;//令temp=0;恢复初始值
return value;
}
}
FIFO算法
定义:该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
import java.util.LinkedList;
public class FIFO {
public void F(int[] seq,int pages) {
int page_break = 0;// 断页次数
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < seq.length; i++) {
if (list.contains(seq[i])) {// 如果即将访问的序列在物理块中,直接跳过
continue;
} else {// 如果即将访问的序列不在物理块中,添加到物理块中;如果满了,找到最久不被访问的序列,并删除替换
if(list.size()!=pages) {
list.addLast(seq[i]);// 该方法表示将指定的元素追加到此列表的末尾
page_break++;//访问序列不存在,断页加一
}else {
list.removeFirst();// 删除第一个元素
list.addLast(seq[i]);// 追加最后一个新元素
page_break++;// 置换,断页加一
}
}
}
// 输出结果
System.out.println("断页次数:" + page_break + "\n断页中断率:" + page_break * 1.0 / seq.length);
}
}
LRU算法
定义:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。
import java.util.LinkedList;
public class LRU {
public void L(int[] seq,int pages){
int page_break = 0;// 断页次数
// 储存容器,LinkedList底层通过链表来实现,随着元素的增加不断向链表的后端增加节点
LinkedList<Integer> list = new LinkedList<Integer>();
// 通过for循环来遍历seq数组
for (int i = 0; i < seq.length; i++) {
if (list.contains(seq[i])) {// 如果即将访问的序列在物理块中,重新记录其访问状态
int flag = list.indexOf(seq[i]);// 标记已经存在的序列的下标
list.remove(flag);// 删除这个元素
list.addLast(seq[i]);// 在末尾重新添加它
} else {// 如果即将访问的序列不在物理块中,添加到物理块中;如果满了,找到最久不被访问的序列,并删除替换
if(list.size()!=pages) {
list.addLast(seq[i]);// 该方法表示将指定的元素追加到此列表的末尾
page_break++;//访问序列不存在,断页加一
}else {
list.removeFirst();// 删除第一个元素
list.addLast(seq[i]);// 追加最后一个新元素
page_break++;// 置换,断页加一
}
}
}
// 输出结果
System.out.println("断页次数:" + page_break + "\n断页中断率:" + page_break * 1.0 / seq.length);
}
}
最后合在一起,测试一下,代码如下:
public class Demo {
public static void main(String[] args) {
while(true) {
int pages = 0;// 定义页面框数
int num = 0;// 定义选择数字
Scanner scan = new Scanner(System.in);
System.out.println("请输入用户访问序列走向:");
String str = scan.nextLine();// 获取序列
String[] str1 = str.split(" ");// 将获取的访问序列用分隔符空格分装到字符串数组里
int[] seq=new int[str1.length];// 定义访问序列
for (int i = 0; i < str1.length; i++) {
seq[i] = Integer.valueOf(str1[i]);// 将String数组转化为int数组
}
System.out.println("请输入页面框数:");
pages = scan.nextInt();// 获取页面框数
System.out.println("**** 1、FIFO ****");
System.out.println("**** 2、LRU ****");
System.out.println("**** 3、OPT ****");
num = scan.nextInt();// 获取选择的数字
switch (num) {
case 1:
new FIFO().F(seq, pages);
break;
case 2:
new LRU().L(seq, pages);
break;
case 3:
new OPT().O(seq, pages);;
break;
default:
System.out.println("输入错误,请重新输入");
break;
}
}
}
}
测试结果如下:
实验测试结果的表格版:
OPT:
FIFO:
LRU:
注:这里引用的三个表格及测试的例子均出自博主子书阳。
三种算法讲解如下:
OPT讲解
FIFO讲解
LRU讲解