操作系统实验之虚拟存储管理实验

页面置换算法:

最佳置换算法(OPT)

先进先出算法(FIFO)

最近最少用算法(LRU)

这个实验的程序打印出每个页面置换算法的页面置换变化示意图、缺页中断次数和缺页中断率,从中可以看出各种算法的优缺点。

代码如下:

package virtualStorageManagement;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;

public class virtualStorageManagement {
	
	public static void main(String args[]) {
		Arithmetic.chooseArithmetic();
	}
}
class Arithmetic{
	static int changePageCount = 0;		//页面中断次数
	static int physicalBlocks = 3;	//静态变量物理块数
	static int PageNum = 8;			//静态变量页数
	Queue<Integer> queue;
	int queueSize;
	Queue<Integer> optQueue;
	PageTable pageTable = new PageTable();			//初始化页表
	BlocksTable blocksTable = new BlocksTable();	//初始化物理块表
	boolean firstPrint = true;
	public static void chooseArithmetic() {
		System.out.println("请选择页面置换算法");
		System.out.println("1.OPT页面置换算法");
		System.out.println("2.FIFO页面置换算法");
		System.out.println("3.LRU页面置换算法");
		System.out.println("4.退出");
		Scanner in = new Scanner(System.in);
		int item = in.nextInt();
		
		while(true) {
			Arithmetic test = new Arithmetic();
			if(item == 1) {
				test.OptArithmetic();
			}
			else if(item == 2) {
				test.FIFOArithmetic();
			}
			else if(item == 3) {
				test.LRUArithmetic();
			}
			else return;
			System.out.println("请选择页面置换算法");
			System.out.println("1.OPT页面置换算法");
			System.out.println("2.FIFO页面置换算法");
			System.out.println("3.LRU页面置换算法");
			System.out.println("4.退出");
			item = in.nextInt();
		}
	}
	public void input() {
		System.out.println("请输入页面访问序列,输入-1结束输入");
		Scanner in = new Scanner(System.in);
		queue = new LinkedList<Integer>();
		int temp = -1;
		temp = in.nextInt();
		while(temp != -1) {
			queue.offer(temp);
			temp = in.nextInt();
		}
		queueSize = queue.size();
	}

	int findMaxDistance(int []temp) {
		int lenth = temp.length;
		int max = temp[0];
		int maxItem = 0;
		for(int i = 1;i < lenth;i++) {
			if(max < temp[i])
			{
				maxItem = i;
				max = temp[i];
			}
		}
		return maxItem;
	}
	public void  changePageOpt(Queue<Integer> tempQueue,int needEnterPage) {
		//新建一个数组存储每个物理块当前页面距离下次用到的距离
		int[] distanceRecord = new int[Arithmetic.physicalBlocks];
		//建立一个关于当前物理块的迭代器
		Iterator<physicalBlocks> it = blocksTable.BlockQueue.iterator();
		//记录当前迭代器迭代到哪个物理块
		int countRecord = 0;
		//用循环确定每个物理块的距离
		 while (it.hasNext()) {//外层循环遍历物理块
	        	physicalBlocks pTemp = it.next();
	        	Iterator<Integer> numIterator = tempQueue.iterator();
	        	//记录距离
	        	int countdistance = 1;
	        	//内层循环遍历所有的输入序列
	        	while(numIterator.hasNext()) {
	        		countdistance++;
	        		int tempPage = numIterator.next();
	        		if(pTemp.usePage == tempPage) {
	        			break;
	        		}
	        	}
	        	distanceRecord[countRecord] = countdistance;
	        	countRecord++;
	        }
		int maxItem = findMaxDistance(distanceRecord);
		//获取需要移除的页面的页号
		int oldRemovePage = blocksTable.getBlocksByNum(maxItem).usePage;
		//把移出主存的页面置为false
		pageTable.changePageState(oldRemovePage, false);
		//把要装入主存的页号传给物理块
		blocksTable.getBlocksByNum(maxItem).usePage =  needEnterPage;
		//把移入主存的页面置为true
		pageTable.changePageState( needEnterPage, true);
		blocksTable.hasChange = true;
		changePageCount++;
	}
	public void OptArithmetic() {
		changePageCount = 0;
		input();
		//获得一个输入序列的复制序列
		System.out.println("\tOPT页面置换算法");
		Queue<Integer> tempQueue = new LinkedList<Integer>(queue);
		while(!tempQueue.isEmpty()) {
			int tempPageNum = tempQueue.poll();
			//判断是否有空的物理块
			if(!blocksTable.haveFullBlocks()) {
				//判断该页面是否在内存里
				if(!pageTable.isInMeomory(tempPageNum)) {
					//不在则调用更换页面算法将距离最长的页面置换出去
					changePageOpt(new LinkedList<Integer>(tempQueue),tempPageNum);
				}
				//如果当前页面在物理块中则什么也不做
			}else { //如果有空的物理块
				physicalBlocks tempBlocks = blocksTable.returnAFullBlock();
				tempBlocks.use = true;
				tempBlocks.usePage = tempPageNum;
				blocksTable.hasChange = true;
				pageTable.changePageState( tempPageNum, true);
				changePageCount++;
			}
			showPhysicalBlocksSituation(tempPageNum,1);
			if(blocksTable.hasChange == true) {
				System.out.println("+");
				blocksTable.hasChange = false;
			}
			else {
				System.out.println("");
			}
		}
		System.out.println("\t<+表示产生一次缺页中断>");
		System.out.println("该算法一共发生了 " + changePageCount + " 次页面置换,缺页中断率为 " + changePageCount*100/queue.size()+ "%\n" ); 
	}
	//FIFO置换算法
	public void FIFOArithmetic() {
		changePageCount = 0;
		input();
		//获得一个输入序列的复制序列
		Queue<Integer> tempQueue = new LinkedList<Integer>(queue);
		int tempQueueSize = tempQueue.size();
		System.out.println("\tFIFO页面置换算法");
		while(!tempQueue.isEmpty()) {
			int tempPageNum = tempQueue.poll();
			//判断是否有空的物理块
			if(!blocksTable.haveFullBlocks()) {
				//判断该页面是否在内存里
				if(!pageTable.isInMeomory(tempPageNum)) {
					//不在则调用更换页面算法将距离最长的页面置换出去
					changePageFIFO(new LinkedList<Integer>(tempQueue),tempPageNum);
					
				}
				else {
				}
			}else { //如果有空的物理块
				physicalBlocks tempBlocks = blocksTable.returnAFullBlock();
				tempBlocks.use = true;
				tempBlocks.usePage = tempPageNum;
				blocksTable.hasChange = true;
				pageTable.changePageState( tempPageNum, true);
				changePageCount++;
			}
			showPhysicalBlocksSituation(tempPageNum,2);
			if(blocksTable.hasChange == true) {
				System.out.println("+");
				blocksTable.hasChange = false;
			}
			else {
				System.out.println("");
			}
		}
		System.out.println("\t<+表示产生一次缺页中断>");
		System.out.println("该算法一共发生了 " + changePageCount + " 次页面置换,缺页中断率为 " + changePageCount*100/tempQueueSize+ "%\n" ); 
		
	}
	public void changeUsePageToLast(int usePage) {
		Iterator<physicalBlocks> it = blocksTable.BlockQueue.iterator();
		Queue<physicalBlocks> tempBlockQueue = new LinkedList<physicalBlocks>();
		physicalBlocks tempBlock;
		physicalBlocks lastBlock = null;
		while(it.hasNext()) {
			tempBlock = it.next();
			if(tempBlock.usePage == usePage) {
				lastBlock = tempBlock;
			}
			else {
				tempBlockQueue.offer(tempBlock);
			}
		}
		tempBlockQueue.offer(lastBlock);
		blocksTable.BlockQueue.poll();
		blocksTable.BlockQueue = tempBlockQueue;
	}
	public void  changePageFIFO(Queue<Integer> tempQueue,int needEnterPage) {
		
		//建立一个关于当前物理块的迭代器
		Iterator<physicalBlocks> it = blocksTable.BlockQueue.iterator();
		int oldPageNum;
		physicalBlocks firstBlock = it.next();
		firstBlock.blockNum = physicalBlocks - 1;
		oldPageNum = firstBlock.usePage;
		firstBlock.usePage = needEnterPage;
		while (it.hasNext()) {//循环遍历物理块将物理块块号减一
        	physicalBlocks pTemp = it.next();
        	pTemp.blockNum -= 1;
		}
		blocksTable.BlockQueue.poll();
		blocksTable.BlockQueue.offer(firstBlock);
		//把移出主存的页面置为false
		pageTable.changePageState(oldPageNum, false);
		//把移入主存的页面置为true
		pageTable.changePageState( needEnterPage, true);
		blocksTable.hasChange = true;
		changePageCount++;
	}
	//LRU算法
		public void LRUArithmetic() {
			changePageCount = 0;
			input();
			System.out.println("\tLRU页面置换算法");
			//获得一个输入序列的复制序列
			Queue<Integer> tempQueue = new LinkedList<Integer>(queue);
			while(!tempQueue.isEmpty()) {
				int tempPageNum = tempQueue.poll();
				//判断是否有空的物理块
				if(!blocksTable.haveFullBlocks()) {
					//判断该页面是否在内存里
					if(!pageTable.isInMeomory(tempPageNum)) {
						//不在则调用更换页面算法将距离最长的页面置换出去
						changePageLRU(new LinkedList<Integer>(tempQueue),tempPageNum);
					}
					else {
						changeUsePageToLast(tempPageNum);
					}
				}else { //如果有空的物理块
					physicalBlocks tempBlocks = blocksTable.returnAFullBlock();
					tempBlocks.use = true;
					tempBlocks.usePage = tempPageNum;
					blocksTable.hasChange = true;
					pageTable.changePageState( tempPageNum, true);
					changePageCount++;
				}
				showPhysicalBlocksSituation(tempPageNum,3);
				if(blocksTable.hasChange == true) {
					System.out.println("+");
					blocksTable.hasChange = false;
				}
				else {
					System.out.println("");
				}
			}
			 System.out.println("\t<+表示产生一次缺页中断>");
			 System.out.println("该算法一共发生了 " + changePageCount + " 次页面置换,缺页中断率为 " + changePageCount*100/queue.size()+ "%\n" ); 
		}
		public void  changePageLRU(Queue<Integer> tempQueue,int needEnterPage) {
			
			//建立一个关于当前物理块的迭代器
			Iterator<physicalBlocks> it = blocksTable.BlockQueue.iterator();
			int oldPageNum;
			physicalBlocks firstBlock = it.next();
			firstBlock.blockNum = physicalBlocks - 1;
			oldPageNum = firstBlock.usePage;
			firstBlock.usePage = needEnterPage;
			while (it.hasNext()) {//循环遍历物理块将物理块块号减一
	        	physicalBlocks pTemp = it.next();
	        	pTemp.blockNum -= 1;
			}
			blocksTable.BlockQueue.poll();
			blocksTable.BlockQueue.offer(firstBlock);
			//把移出主存的页面置为false
			pageTable.changePageState(oldPageNum, false);
			//把移入主存的页面置为true
			pageTable.changePageState( needEnterPage, true);
			blocksTable.hasChange = true;
			changePageCount++;
		}
	void showPhysicalBlocksSituation(int enterPage,int printMode) {
		Iterator<physicalBlocks> it = blocksTable.BlockQueue.iterator();
		if(printMode == 1) {
			if(firstPrint == true){
				System.out.println("调用页面\t物理块1\t物理块2\t物理块3\t");
				firstPrint = false;
			}
			System.out.print(enterPage + "\t");
			while (it.hasNext()) {
	        	physicalBlocks bTemp = it.next();
	        	if(bTemp.use == true) {
	        		System.out.print(bTemp.usePage + "\t");
	        	}
	        	else {
	        		System.out.print("空\t");
	        	}
	        }
		}
		else if(printMode == 2 || printMode == 3) {
			if(printMode == 2){
				if(firstPrint == true){
					System.out.println("调用页面\t最新页面\t中间页面\t最旧页面\t");
					firstPrint = false;
				}
			}
			else if(printMode == 3) {
				if(firstPrint == true){
					System.out.println("调用页面\t常用页面\t中间页面\t少用页面\t");
					firstPrint = false;
				}
			}
			System.out.print(enterPage + "\t");
			Stack<physicalBlocks> stackBlock =new Stack<physicalBlocks>();
			int countNull = 0;
			while(it.hasNext()) {
				physicalBlocks temp = it.next();
				if(temp.use == false)
					countNull++;
				else
					stackBlock.push(temp);
			}
			while (!stackBlock.empty()) {
	        	physicalBlocks bTemp = stackBlock.pop();
	        	System.out.print(bTemp.usePage + "\t");
	        }
			while (countNull-- > 0) {
	        	System.out.print("空\t");
	        }
			
		}
	}
}
//定义物理块
class physicalBlocks{
	int blockNum;
	boolean use = false;
	int usePage = -1;
	
}
//定义物理块表
class BlocksTable{
	Queue<physicalBlocks> BlockQueue;
	boolean hasChange = false;
	BlocksTable(){
		initial();
	}
	void initial() {
		BlockQueue = new LinkedList<physicalBlocks>();
		for(int i = 0;i < Arithmetic.physicalBlocks;i++) {
			physicalBlocks bTemp = new physicalBlocks();
			bTemp.use = false;
			bTemp.blockNum = i;
			BlockQueue.offer(bTemp);
		}
	}
	boolean haveFullBlocks() {
		Iterator<physicalBlocks> it = BlockQueue.iterator();
        while (it.hasNext()) {
        	physicalBlocks bTemp = it.next();
        	if(bTemp.use == false) {
        		return true;
        	}
        }
        return false;
	}
	physicalBlocks returnAFullBlock(){
		Iterator<physicalBlocks> it = BlockQueue.iterator();
        while (it.hasNext()) {
        	physicalBlocks bTemp = it.next();
        	if(bTemp.use == false) {
        		return bTemp;
        	}
        }
        return null;
	}
	Iterator<physicalBlocks> getIterator(){
		return BlockQueue.iterator();
	}
	physicalBlocks getBlocksByNum(int num) {
		Iterator<physicalBlocks> it = BlockQueue.iterator();
        while (it.hasNext()) {
        	physicalBlocks bTemp = it.next();
        	if(bTemp.blockNum == num) {
        		return bTemp;
        	}
        }
        return null;
	}
}
//定义每一页
class Page{
	int pageNum;
	boolean inMemory = false;
}
//定义一个页表
class PageTable{
	int PageNum = 8;
	Queue<Page> PageQueue; 
	PageTable(){
		initial();
	}
	void initial() {
		PageQueue = new LinkedList<Page>();
		for(int i = 0;i < Arithmetic.PageNum;i++) {
			Page pTemp = new Page();
			pTemp.pageNum = i;
			PageQueue.offer(pTemp);
		}
	}
	boolean isInMeomory(int PageNum){
		 Iterator<Page> it = PageQueue.iterator();
	        while (it.hasNext()) {
	        	Page pTemp = it.next();
	        	if(pTemp.pageNum == PageNum) {
	        		if(pTemp.inMemory == false) {
	        			return false;
	        		}
	        		else {
	        			return true;
	        		}
	        	}
	        }
	        return false;
	}
	void changePageState(int PageNum,boolean setInMemory) {
		Iterator<Page> it = PageQueue.iterator();
        while (it.hasNext()) {
        	Page pTemp = it.next();
        	if(pTemp.pageNum == PageNum) {
        		//1代表在页在主存中,0代表页不在主存中
        		pTemp.inMemory = setInMemory;
        		break;
        	}
        }
	}
}

实验结果如下如下:

 

 

 

 

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值