(操作系统实验)内存页面淘汰算法---FIFO、LRU、OPT

算法介绍

参考操作系统或计算机组成原理相关教材,很容易理解,介绍略。可以参考笔者后续实验结果,有助于理解算法。

源代码

由于算法简单,不再进行画图设计思路,笔者直接编写代码,遇到问题随之解决。下面是源代码文件,只有一个文件,Main.java,使用文件输入,输入文件是in.txt,注意把该输入文件和Main.java放在同一个文件夹下,再用命令行编译运行即可。


import java.util.*;
import java.io.*;
import java.time.format.FormatStyle;

public class Main{
//仅仅为了操作方便,本程序就是用面向对象的语言写结构化程序,都是public级别

	public ArrayList<Integer> pageList;//页走向序列
	public ArrayList<Integer> pageTable;//这个是存储页的表
	public int size;//页框大小
	public ArrayList<String> pathList;//用于记录路径
	public int missingPage;
	public static final int MAX = 10000;

	public Main(){}

	public static void main(String[] args){
		new Main().run();
	}

	public void run(){
		this.input();//文件输入数据
		System.out.print("请输入页框大小:");
		Scanner scan = new Scanner(System.in);
		this.size = scan.nextInt();
		this.OPT();
		this.FIFO();
		this.LRU();
	}
	
	public void input(){
		pageList = new ArrayList<Integer>();
		pageTable = new ArrayList<Integer>();
		pathList = new ArrayList<String>();
		try{
			File file = new File("in.txt");
			BufferedReader br = new BufferedReader(new FileReader(file));
			String str = br.readLine(); 
			if(str!=null){
				String[] splits = str.split(" ");
				for(int i = 0; i < splits.length; i++){
					this.pageList.add(Integer.valueOf(splits[i]));
				}	
			}
			br.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void print(){
		
		System.out.println("--------------------------------------------------------------------");
		System.out.print("pages");
		for(int i = 0; i < pageList.size(); i++){
			System.out.print(" "+pageList.get(i));
		}
		System.out.println();
		for(int i = 0; i < size; i++){
			System.out.print("page"+(i+1));
			for(int j =0; j< pathList.size(); j++){
				System.out.print("\t"+pathList.get(j).charAt(i));
			}
			System.out.println();
		}
		System.out.print("     ");
		for(int j =0; j< pathList.size(); j++){
			System.out.print("\t"+pathList.get(j).charAt(pathList.get(j).length()-1));
		}
		System.out.println();
		System.out.println("共发生"+missingPage+"次缺页中断");
		System.out.println("--------------------------------------------------------------------");
		System.out.println();
	}

	public void OPT(){
		boolean missingPageMark = false;
		missingPage = 0;
		for(int i = 0; i < this.pageList.size(); i++){
			missingPageMark = false;
			if(pageTable.size() < this.size){//如果当前页框尚没有满
				if(pageTable.contains(pageList.get(i))==false){
					missingPageMark = true;
					pageTable.add(0, pageList.get(i));
					missingPage++;
				}else {
					
				}
				
			}else{
				if(pageTable.contains(pageList.get(i))){//页框中含有该页
					
				}else{//缺页中断
					missingPageMark=true;
					missingPage++;
					//搜索一下当前表中的每个页距离下次出现还有多少距离
					int[] distances = new int[size];
					for(int j = 0; j < size; j++){
						int tmpCnt = 1;
						boolean flag = false;//标志下是否能找到再次出现
						for(int k = i; k < pageList.size(); k++){
							if(pageList.get(k) != pageTable.get(j)){
								tmpCnt++;
							}else{
								flag =true;
								break;
							}
						}
						if(flag){
							distances[j] = tmpCnt;
						}else{
							distances[j] = MAX;
						}
					}
					int max = -1;
					int loc = -1;
					//找到最大距离的页的位置
					for(int kk = 0; kk < size; kk++){
						if(distances[kk] > max){
							max = distances[kk];
							loc = kk;
						}
					}
					//把该页替换掉即可
					pageTable.set(loc, pageTable.get(0));
					pageTable.set(0, pageList.get(i));
				}
			}
			//记录路径
			String pathTmp = "";
			for(int m=0; m<pageTable.size();m++){
				pathTmp += pageTable.get(m);
			}
			for(int m = pageTable.size(); m< size; m++){
				pathTmp += " ";
			}
			if(missingPageMark) {pathTmp+="X";}
			else {pathTmp+="√";}
			pathList.add(pathTmp);
		}
		System.out.println("OPT:");
		print();
		pageTable.clear();//清空页表
		pathList.clear();
	}
	
	public void FIFO(){
		missingPage=0;
		boolean missingPageMark = false;
		for(int i = 0; i < this.pageList.size(); i++){
			missingPageMark=false;
			
			if(pageTable.size() < this.size){//如果当前页框尚没有满
				if(pageTable.contains(pageList.get(i))==false){
					missingPageMark = true;
					pageTable.add(0, pageList.get(i));
					missingPage++;
				}else {
					if(pageTable.size()==1) {
						
					}else {
						pageTable.remove(pageList.get(i));
						pageTable.add(0, pageList.get(i));
					}
				}
			}else{
				if(pageTable.contains(pageList.get(i))){//页框中含有该页
					
				}else{//缺页中断
					missingPageMark=true;
					missingPage++;
					pageTable.add(0, pageList.get(i));	
					pageTable.remove(pageTable.size()-1);
				}
			}
			//记录路径
			String pathTmp = "";
			for(int m=0; m<pageTable.size();m++){
				pathTmp += pageTable.get(m);
			}
			for(int m = pageTable.size(); m< size; m++){
				pathTmp += " ";
			}
			if(missingPageMark) {pathTmp+="X";}
			else {pathTmp+="√";}
			pathList.add(pathTmp);
		}
		System.out.println("FIFO:");
		print();
		pageTable.clear();//清空页表
		pathList.clear();
	}
	
	public void LRU(){
		missingPage=0;
		boolean missingPageMark = false;
		for(int i = 0; i < this.pageList.size(); i++){
			missingPageMark=false;
			if(pageTable.size() < this.size){//如果当前页框尚没有满
				if(pageTable.contains(pageList.get(i))==false){
					missingPageMark = true;
					pageTable.add(0, pageList.get(i));
					missingPage++;
				}else {
					if(pageTable.size()==1) {
						
					}else {
						pageTable.remove(pageList.get(i));
						pageTable.add(0, pageList.get(i));
					}
				}
			}else{
				if(pageTable.contains(pageList.get(i))){//页框中含有该页
					pageTable.add(0, pageList.get(i));
					pageTable.remove(pageTable.size()-1);
				}else{//缺页中断
					missingPageMark=true;
					missingPage++;
					pageTable.add(0, pageList.get(i));	
					pageTable.remove(pageTable.size()-1);
				}
			}
			//记录路径
			String pathTmp = "";
			for(int m=0; m<pageTable.size();m++){
				pathTmp += pageTable.get(m);
			}
			for(int m = pageTable.size(); m< size; m++){
				pathTmp += " ";
			}
			if(missingPageMark) {pathTmp+="X";}
			else {pathTmp+="√";}
			pathList.add(pathTmp);
		}
		System.out.println("LRU:");
		print();
		pageTable.clear();//清空页表
		pathList.clear();
	}
	
}

输入文件in.txt的数据如下:
4 3 2 1 4 3 5 4 3 2 1 5

在这里插入图片描述

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
完整虚拟存储管理器实验报告!一、实验目的请求页式虚存管理是常用的虚拟存储管理方案之一。通过请求页式虚存管理中对页面置换算法的模拟,有助于理解虚拟存储技术的特点,并加深对请求页式虚存管理的页面调度算法的理解。二、实验环境 Turbo C 2.0/3.0或VC++6.0三、实验内容本实验要求使用C语言编程模拟一个拥有若干个虚页的进程在给定的若干个实页中运行、并在缺页中断发生时分别使用FIFO和LRU算法进行页面置换的情形。其中虚页的个数可以事先给定(例如10个),对这些虚页访问的页地址流(其长度可以事先给定,例如20次虚页访问)可以由程序随机产生,也可以事先保存在文件中。要求程序运行时屏幕能显示出置换过程中的状态信息并输出访问结束时的页面命中率。程序应允许通过为该进程分配不同的实页数,来比较两种置换算法的稳定性。四、实验说明 1.设计中虚页和实页的表示本设计利用C语言的结构体来描述虚页和实页的结构。pnpfntimepnpfnnext 虚页结构 实页结构在虚页结构中,pn代表虚页号,因为共10个虚页,所以pn的取值范围是0—9。pfn代表实页号,当一虚页未装入实页时,此项值为-1;当该虚页已装入某一实页时,此项值为所装入的实页的实页号pfn。time项在FIFO算法中不使用,在LRU中用来存放对该虚页的最近访问时间。在实页结构中,pn代表虚页号,表示pn所代表的虚页目前正放在此实页中。pfn代表实页号,取值范围(0—n-1)由动态指派的实页数n所决定。next是一个指向实页结构体的指针,用于多个实页以链表形式组织起来,关于实页链表的组织详见下面第4点。2.关于缺页次数的统计为计算命中率,需要统计在20次的虚页访问中命中的次数。为此,程序应设置一个计数器count,来统计虚页命中发生的次数。每当所访问的虚页的pfn项值不为-1,表示此虚页已被装入某实页内,此虚页被命中,count加1。最终命中率=count/20*100%。3.LRU算法中“最近最久未用”页面的确定为了能找到“最近最久未用”的虚页面,程序中可引入一个时间计数器countime,每当要访问一个虚页面时,countime的值加1,然后将所要访问的虚页的time项值设置为增值后的当前countime值,表示该虚页的最后一次被访问时间。当LRU算法需要置换时,从所有已分配实页的虚页中找出time值为最小的虚页就是“最近最久未用”的虚页面,应该将它置换出去。4.算法中实页的组织因为能分配的实页数n是在程序运行时由用户动态指派的,所以应使用链表组织动态产生的多个实页。为了调度算法实现的方便,可以考虑引入free和busy两个链表:free链表用于组织未分配出去的实页,首指针为free_head,初始时n个实页都处于free链表中;busy链表用于组织已分配出去的实页,首指针为busy_head,尾指针为busy_tail,初始值都为null。当所要访问的一个虚页不在实页中时,将产生缺页中断。此时若free链表不为空,就取下链表首指针所指的实页,并分配给该虚页。若free链表为空,则说明n个实页已全部分配出去,此时应进行页面置换:对于FIFO算法要将busy_head 所指的实页从busy链表中取下,分配给该虚页,然后再将该实页插入到busy链表尾部;对于LRU算法则要从所有已分配实页的虚页中找出time值为最小的虚页,将该虚页从装载它的那个实页中置换出去,并在该实页中装入当前正要访问的虚页。~
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值