操作系统--页面置换算法(先进先出算法,最近最久未使用算法,最佳置换算法)--JAVA实现

模拟操作系统对内存与虚拟内存的页面置换算法,当分配的内存不足时,进行替换

大家直接看代码吧,里面的注释应该够了,这三个程序结构差不多,只是在替换算法有差别

1.先看最简单的先入先出算法:

public class FIFO {

	/**
	 *先进先出算法
	 */
	private static final int PRO_MEMORY = 5;//系统分配的内存块数
	private static Page[] pages = new Page[PRO_MEMORY];
	private static int countOldPoint ;//纪录最久的页面下标
	private static int count ;//纪录当前在使用的总页面数
	private static int lackTime;//缺页次数
	private List<Integer> usePageNumList = new ArrayList<Integer>();//页面使用列表
	
	public static void main(String[] args){
		System.out.println("--------先进先出算法------------");
		FIFO fifo = new FIFO();
		fifo.init();
		fifo.input();
		fifo.running();
	}
	
	//初始化
	public  void init(){
		for(int i=0;i<pages.length;i++){
			pages[i] = new Page();
		}
	}
	//接收用户输入列表
	public void input(){
		System.out.print("请输入页面使用列表,以空格分开:");
		Scanner sc = new Scanner(System.in);
		String input = sc.nextLine();
		String[] inputList = input.split("\\s");
		try{
			for(String in : inputList){
				usePageNumList.add(Integer.valueOf(in));
			}
		}
		catch(Exception e){
			System.out.println("输入的必须是数字,请重新开始!!!");
			System.exit(0);
		}
	}
	//系统运行
	public void running(){
		Iterator<Integer> it = usePageNumList.iterator();
		//列表置入替换
		while(it.hasNext()){
			countOldPoint = countOldPoint % PRO_MEMORY;
			int inPageId = it.next();
			//查找内存中是否有该页面
			if(search(inPageId)){
				System.out.println("内存中有ID为"+inPageId+" 这个页面,不进行替换");
			}
			else if(count<PRO_MEMORY){//有空闲内存页
				pages[count].setId( (Integer)inPageId);
				System.out.println("页号ID:"+pages[count].getId()+" 正在放入内存");
				count ++;
			}
			else{//替换
				replace(inPageId);
				lackTime ++;
				countOldPoint ++;
			}
			display();
		}
		System.out.println("缺页次数为:"+lackTime+",缺页率是:"+(float)lackTime/usePageNumList.size());
	}
	//查找内存中是否有该页面
	public boolean search(int pageId){
		for(int i=0;i<pages.length;i++){
			if(pages[i].getId() == pageId){
				return true;
			}
		}
		return false;
	}
	
	//替换算法
	public void replace(int pageId){
		//置换最久的页面
		int outPageId = -1;
		outPageId = pages[countOldPoint].getId();
		pages[countOldPoint].setId(pageId);
		System.out.println("页号ID:"+pageId+" 正在放入内存,页号ID:"+outPageId+"被替换出去");
	}	
	//显示当前内存页
	public void display(){
		System.out.print("当前内存保留的页数是:");
		for(Page page : pages){
			System.out.print(page.getId()+" ");
		}
		System.out.println();
	}

}


2.最佳置换算法:这算法实际不可实现,当然现在我们手工输入程序运行需要哪些页面,实际是不知道的

public class OPT {

	/**
	 * 最佳置换算法
	 */
	private static final int PRO_MEMORY = 5;//系统分配的内存块数
	private static Page2[] pages = new Page2[PRO_MEMORY];
	private static int count ;//纪录当前在使用的总页面数
	private static int lackTime;//缺页次数
	private List<Integer> usePageNumList = new ArrayList<Integer>();//页面使用列表
	public static void main(String[] args) {
		System.out.println("-------- 最佳置换算法------------");
		OPT opt = new OPT();
		opt.init();
		opt.input();
		opt.running();
	}
	//初始化
	public  void init(){
		for(int i=0;i<pages.length;i++){
			pages[i] = new Page2();
		}
	}
	//接收用户输入列表
	public void input(){
		System.out.print("请输入页面使用列表,以空格分开:");
		Scanner sc = new Scanner(System.in);
		String input = sc.nextLine();
		String[] inputList = input.split("\\s");
		try{
			for(String in : inputList){
				usePageNumList.add(Integer.valueOf(in));
			}
		}
		catch(Exception e){
			System.out.println("输入的必须是数字,请重新开始!!!");
			System.exit(0);
		}
	}
	//系统运行
	public void running(){
		Iterator<Integer> it = usePageNumList.iterator();
		int currentPoint = 0;//当前读取输入列表的下标
		//列表置入替换
		while(it.hasNext()){
			int inPageId = it.next();
			//查找内存中是否有该页面
			if(search(inPageId)){
				System.out.println("内存中有ID为"+inPageId+" 这个页面,不进行替换");
			}
			else if(count<PRO_MEMORY){//有空闲内存页
				pages[count].setId( (Integer)inPageId);
				System.out.println("页号ID:"+pages[count].getId()+" 正在放入内存");
				count ++;
				timeRefresh();
			}
			else{//替换
				replace(inPageId,currentPoint);//传入当前下标确定需要遍历的未来输入列表
				timeRefresh();
				lackTime ++;
			}
			currentPoint ++;
			display();
		}
		System.out.println("缺页次数为:"+lackTime+",缺页率是:"+(float)lackTime/usePageNumList.size());
	}
	//查找内存中是否有该页面
	public boolean search(int pageId){
		for(int i=0;i<pages.length;i++){
			if(pages[i].getId() == pageId){
				timeRefresh();
				return true;
			}
		}
		return false;
	}
	//时间更新
	public void timeRefresh(){
		for(Page2 page : pages){
			page.inc();
		}
	}
	//替换算法
	public void replace(int pageId,int currentPoint){
		//寻找最长时间不使用的页面,count最大的内存块
		int max = 0,perCount,outPageId = -1,cur = 0,searchCounter=0;//cur为内存块下标,searchCounter纪录是否内存块搜索完毕
		//循环爆出最长为使用的页面
		for(int i=currentPoint+1;i<usePageNumList.size();i++){
			for(Page2 page : pages){
				if(page.getId() == usePageNumList.get(i)){
					searchCounter ++;
				}
				else{
					page.inc();//未找到则增长值
				}
			}
			if(searchCounter == pages.length){
				break;
			}
		}
		//进行搜索,查找替换目标
		for(int i=0;i<pages.length;i++){
			perCount = pages[i].getCount();
			if(max<perCount){
				max = perCount;
				cur = i;
				outPageId = pages[i].getId();
			}
//			System.out.println("--------当前-页号count------->"+perCount);
		}
		pages[cur].setId(pageId);
		System.out.println("页号ID:"+pageId+" 正在放入内存,页号ID:"+outPageId+"被替换出去");
		reSet();
	}
	//搜索完毕进行重置
	public void reSet(){
		for(Page2 page : pages){
			page.setCount(0);
		}
	}
	
	//显示当前内存页
	public void display(){
		System.out.print("当前内存保留的页数是:");
		for(Page2 page : pages){
			System.out.print(page.getId()+" ");
		}
		System.out.println();
	}
	
}
/*
 * 未来最久未使用纪录
 */
class Page2{
	private int id = -1;
	private int count;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getCount() {
		return count;
	}
	public void inc() {
		count ++;
	}
	public void setCount(int count) {
		this.count = count;
	}
}

3.最近最久未使用算法

public class LRU {
	/**
	 * 最近最久未使用算法
	 */
	private static final int PRO_MEMORY = 5;//系统分配的内存块数
	private static Page[] pages = new Page[PRO_MEMORY];
	private static int count ;//纪录当前在使用的总页面数
	private static int lackTime;//缺页次数
	private List<Integer> usePageNumList = new ArrayList<Integer>();//页面使用列表
	public static void main(String[] args) {
		System.out.println("--------最近最久未使用算法------------");
		LRU lru = new LRU();
		lru.init();
		lru.input();
		lru.running();
	}
	//初始化
	public  void init(){
		for(int i=0;i<pages.length;i++){
			pages[i] = new Page();
		}
	}
	//接收用户输入列表
	public void input(){
		System.out.print("请输入页面使用列表,以空格分开:");
		Scanner sc = new Scanner(System.in);
		String input = sc.nextLine();
		String[] inputList = input.split("\\s");
		try{
			for(String in : inputList){
				usePageNumList.add(Integer.valueOf(in));
			}
		}
		catch(Exception e){
			System.out.println("输入的必须是数字,请重新开始!!!");
			System.exit(0);
		}
	}
	//系统运行
	public void running(){
		Iterator<Integer> it = usePageNumList.iterator();
		//列表置入替换
		while(it.hasNext()){
			int inPageId = it.next();
			//查找内存中是否有该页面
			if(search(inPageId)){
				System.out.println("内存中有ID为"+inPageId+" 这个页面,不进行替换");
			}
			else if(count<PRO_MEMORY){//有空闲内存页
				pages[count].setId( (Integer)inPageId);
				System.out.println("页号ID:"+pages[count].getId()+" 正在放入内存");
				reSet(count);
				count ++;
				timeRefresh();
			}
			else{//替换
				replace(inPageId);
				timeRefresh();
				lackTime ++;
			}
			display();
		}
		System.out.println("缺页次数为:"+lackTime+",缺页率是:"+(float)lackTime/usePageNumList.size());
	}
	//查找内存中是否有该页面
	public boolean search(int pageId){
		for(int i=0;i<pages.length;i++){
			if(pages[i].getId() == pageId){
				timeRefresh();
				reSet(i);
				return true;
			}
		}
		return false;
	}
	//访问后置0
	public void reSet(int cur){
		pages[cur].setCount(0);
	}
	//时间更新
	public void timeRefresh(){
		for(Page page : pages){
			page.inc();
		}
	}
	//替换算法
	public void replace(int pageId){
		//寻找时间数最大的页面
		int max = 0,perCount,outPageId = -1,cur = 0;//cur为下标
		for(int i=0;i<pages.length;i++){
			perCount = pages[i].getCount();
			if(max<perCount){
				max = perCount;
				outPageId = pages[i].getId();//换出去的页号
				cur = i;
			}
		}
		reSet(cur);
		pages[cur].setId(pageId);
		System.out.println("页号ID:"+pageId+" 正在放入内存,页号ID:"+outPageId+"被替换出去");
	}	
	
	//显示当前内存页
	public void display(){
		System.out.print("当前内存保留的页数是:");
		for(Page page : pages){
			System.out.print(page.getId()+" ");
		}
		System.out.println();
	}
	
}
/*
 * 页面
 */
class Page{
	private int id = -1;
	private int count;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getCount() {
		return count;
	}
	public void inc() {
		count ++;
	}
	public void setCount(int count) {
		this.count = count;
	}
}



尾注:文章来自 http://blog.csdn.net/mzlqh

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值