页面替换算法FIFO,OPT,LRU的js实现

一.FIFO算法

1.1 先进先出算法基本思想:
淘汰最先进入的页面,选择在内存中驻留最久的页面的予以淘汰。
基本思想就是将先进入队列的页面先淘汰掉,如果该页面后期被命中,那也不将它的步数重置,而是按照它第一次进入页面开始记步数

FIFO

二. LRU算法

2.1 LRU置换算法基本思想:

Lru算法和fifo最大相似点就是淘汰前向步数最大的页面,也就是淘汰页面的判断依据是该页面的从前到后的步数统计,越大表明越是长时间为用到,所以予以淘汰替换。
单很明显是由明显区别的,那就是lru算法当遇到命中时会将该页面重置步数。

LRU

三.Optimal算法:

3.1 最佳置换算法基本思想:
将以后永不使用的淘汰,或者是将在最长(未来)时间内不在访问的页面淘汰。由于不能知道或预测谁是最可能永不使用或者长时间使用的页面,所以不能拿它来作为页面置换实际操作中的算法,但是可以用于评估其他算法。
(未被命中的即为“缺页”,缺页率=未命中数/总数,淘汰率=替换数/总数)
3.2具体操作思想
首先有一个页面访问顺序的数列2,3,1,5,6,7,6,3,7,8,2。内存块有3个物理块
OPT

四.运行截图

在这里插入图片描述

五.代码:

<!DOCTYPE html>
<html>
<head>
	<title>页面替换算法OPT,FIFO,LRU</title>
	<meta charset="utf-8">
	<meta author="syk">
</head>
<link rel="stylesheet" href="reset.css">
<style>
	
.container{
	position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
	
	background: #00ace6;

}
.container-warrper{
	width: 700px;
	padding: 0 0 0 0;
	margin: 100px auto;
	border: 1px dashed #cccccc;
}
.container span{
	color: #ffffff;
}
#liststyle{
	width: 600px;
	background: #ffffff;
	margin-top: 10px;
}
#substyle{
	text-align: center;
}
#part{
	margin: 20px 0 20px 0;
	color: #ffffff;
	text-align: center;
	height: 25px;
	line-height: 25px;
}
.arithmetic{
	
}
#but1 ,#but2 ,#but3{
	border-radius: 50%;
	background-color: bisque;
	outline: none;
	color: #000000;
	font-weight: 700;

}
#result1 ,#result2 ,#result3{
color: #ffffff;
font-weight: 600;
text-align: center;
}
</style>
<body>
<div class="container">
	<div class="container-warrper">
		<form action="#" method="POST">
			<span>页面序列:</span> <input type="text" name="list" id="liststyle" value="" placeholder="请按照'1 2 3 4 . . .'带有空格的方式写 输入7个数吧!!"> <br/>
			<input type="submit" value="确认" id="substyle">
			<p style="color:#ffffff;">-----------------------------------------------------------------------------------------------------</p>
			<p id="part"></p>
		</form>
		<div class="arithmetic">
			<p style="color:#ffffff;">-----------------------------------------------------------------------------------------------------</p>
			<button id="but1">OPT算法</button>
			<button id="but2">FIFO算法</button>
			<button id="but3">LRU算法</button>
			<p style="color:#ffffff;">-----------------------------------------------------------------------------------------------------</p>
			<div id="result1"></div>
			<p style="color:#ffffff;">-----------------------------------------------------------------------------------------------------</p>
			<div id="result2"></div>
			<p style="color:#ffffff;">-----------------------------------------------------------------------------------------------------</p>
			<div id="result3"></div>
		</div>
	</div>
</div>
</body>
<script type="text/javascript">
var Button=document.getElementById('substyle');

var Logic1=document.getElementById('but1');//opt算法对象
var Logic2=document.getElementById('but2');//fifo算法对象
var Logic3=document.getElementById('but3');//lru算法对象

var textlist=document.getElementById('liststyle');
var list =new Array();
var Plist= new Array();//页面序列
var M=new Array();
// M=[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]];//物理存储块向量7
var target=0;
var pointPage=0;//命中数
//实现的是点击获取当前的form表单输入值,置换成数组形式Plist[];
Button.onclick=function(){
	var x=textlist.value;
	list=x.split(" ");
	list.forEach(element => {
		Plist.push(parseInt(element));	
	});		
	console.log(Plist);

	document.getElementById('part').innerHTML="当前的页面调入数组是:["+ Plist +"]";

	console.log(target);
	return false;
}
// var a=1;
// document.getElementById('result1').innerHTML='‘'+a+'’';

// a++;
// document.getElementById('result2').innerHTML='‘'+a+'’';
var headlist=new Array();//上一次的数组
var B=new Array();
var C=new Array();
// C=[0,0,0];
function init(){
	M=[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]];
	C=[0,0,0];
	pointPage=0;
}
Logic1.onclick=()=>{
	console.log("OPT");
	// MisPage=3;
	init();
		Plist.forEach((p,i) => {
			if(i<=2){		//前三个是一定要产生缺页的,所以直接插入
				var w=i;
				for(w;w>=0;w--){
					if(w!=i){
						M[i].splice(w,1,B[w]);		//当没到和当前p匹配的位置时,前面都是引用上一个的数组的值。
					}else{
						M[i].splice(w,1,p);
					}				
				}		//复杂度是一个m*n的空间复杂度。
				B=M[i];
				console.log("M["+M[i]+"]");
				// M[i+1]=B;//数组是引用类型,这里会将地址统一到m[0]处,这样后面的变了,前面的理所当然的变了,所以说这里不是用引用类型!!!。
			// debugger;
			}else{//进入的条件就是数组遍历到了第i=3的位置,这时如果数组是[1,2,3,4,5,1,2],那么就会是4准备入页面了,
						if(M[i-1].some((value)=>{return value==p;})){//命中了!!这里应该用前一个索引作为当前基准,也就是说不应该是i,应为i是外面的,一直没变。。。
						
							M[i-1].forEach((element,indx) => {
								M[i].splice(indx,1,element);
								
							});
							
							pointPage++;
						}else{//没有命中则要发生替换算法了!!,
							for(let [index, item] of Plist.entries()){
								if(index>i-1){//从第4条开始寻找。以后依次往后寻找
									M[i-1].forEach((element,i) => {
									if(element==item){
										if(C[i]!=0&&C[i]<index){	 
										//找最近被替换的索引,怕出现1这个数后面出现两次,结果将大的索引去替换了之前小的索引。
										}else{
											C[i]=index;//当前所需知道的物理存储块的后面所最近出现的位置,位置越大越表示要被替换
										}
									}
								});
							}//最终找到了我们的其前面对应的3个页面各自在后方的最近被访问的索引,下面只需要比较谁大了,越大证明越远被访问到,所以被替换
						}//计算当前被替换的3个物理块中个元素在后面最先调入的索引,也就是我们所说的后面的距离。
						var x=C.indexOf(C.reduce((a,b)=>{return a>b?a:b;}));//得到应该被替换的数组的索引。
						// debugger;
						M[i-1].forEach((element,indx) => {
								M[i].splice(indx,1,element);
						});
						M[i].splice(x,1,p);
						// MisPage++;
					}
					
				// }
			// }
		}		
		});
		// dom操作,添加输出的信息。
		M.forEach((element,index) => {
			// debugger;
			M[index].forEach((e,i)=>{
				console.log(e);
				document.getElementById('result1').innerHTML="<p>["+M+"]</p><br/><p>缺页率:"+(Plist.length-pointPage)/Plist.length+"</p>";//这里用innerHTML最后会被覆盖
			})
			
		});	
}

Logic2.onclick=()=>{//比较的是我们的,主流时间最长的淘汰
	init();
	C=[M[0].length,M[0].length-1,M[0].length-2];
	console.log("FIFO");
	Plist.forEach((p,i) => {
		// debugger;
		if(i<=2){		//前三个是一定要产生缺页的,所以直接插入
				var w=i;
				var stp;
				for(w;w>=0;w--){
					if(w!=i){
						M[i].splice(w,1,B[w]);		//当没到和当前p匹配的位置时,前面都是引用上一个的数组的值。
					
					}else{
						M[i].splice(w,1,p);
					}				
				}		//复杂度是一个m*n的空间复杂度。
				B=M[i];
				console.log("M["+M[i]+"]");
				// M[i+1]=B;//数组是引用类型,这里会将地址统一到m[0]处,这样后面的变了,前面的理所当然的变了,所以说这里不是用引用类型!!!。
			// debugger;
		}else{//开始判断C,和改变C。//声明一下,如果被命中了,则改处的C的计数从1开始
			
			if(M[i-1].some((value)=>{return value==p;})){//命中了!!这里应该用前一个索引作为当前基准,也就是说不应该是i,应为i是外面的,一直没变。。。	
				
						M[i-1].forEach((element,indx) => {
							M[i].splice(indx,1,element);	
						});
						C.forEach((e,idx)=>{
							C.splice(idx,1,e+1);
						})//命中每一个前面等待的加1。
						pointPage++;
			}else{//没命中的话怎么办呢?比较C数组,决定替换最大的那个,
						var x=C.indexOf(C.reduce((a,b)=>{return a>b?a:b;}));//找到最先来的是谁。
						// debugger;
						M[i-1].forEach((element,indx) => {
								M[i].splice(indx,1,element);
						});
						M[i].splice(x,1,p);
						C.forEach((e,idx)=>{
								C.splice(idx,1,e+1);
						});
						C.splice(x,1,1);//与此同时被替换的位置则重置为1。
			}

		}
	});

	M.forEach((element,index) => {
			// debugger;
			M[index].forEach((e,i)=>{
				console.log(e);
				document.getElementById('result2').innerHTML="<p>["+M+"]</p><br/><p>缺页率:"+(Plist.length-pointPage)/Plist.length+"</p>";//这里用innerHTML最后会被覆盖
			})
			
		});	
}


Logic3.onclick=()=>{
	init();
	console.log("LRU");
	init();
	C=[M[0].length,M[0].length-1,M[0].length-2];
	console.log("FIFO");
	Plist.forEach((p,i) => {
		// debugger;
		if(i<=2){		//前三个是一定要产生缺页的,所以直接插入
				var w=i;
				var stp;
				for(w;w>=0;w--){
					if(w!=i){
						M[i].splice(w,1,B[w]);		//当没到和当前p匹配的位置时,前面都是引用上一个的数组的值。
					
					}else{
						M[i].splice(w,1,p);
					}				
				}		//复杂度是一个m*n的空间复杂度。
				B=M[i];
				console.log("M["+M[i]+"]");
				// M[i+1]=B;//数组是引用类型,这里会将地址统一到m[0]处,这样后面的变了,前面的理所当然的变了,所以说这里不是用引用类型!!!。
			// debugger;
		}else{//开始判断C,和改变C。//声明一下,如果被命中了,则改处的C的计数从1开始
			
			if(M[i-1].some((value)=>{return value==p;})){//命中了!!这里应该用前一个索引作为当前基准,也就是说不应该是i,应为i是外面的,一直没变。。。	
				// debugger;
						M[i-1].forEach((element,indx) => {
							M[i].splice(indx,1,element);	
						});
						C.forEach((e,idx)=>{
							if(M[i][idx]==p){
								C.splice(idx,1,1);//和fifo的区别处
							}else{
								C.splice(idx,1,e+1);
							}	
						})//命中每一个前面等待的加1。
						pointPage++;
			}else{//没命中的话怎么办呢?比较C数组,决定替换最大的那个,
						var x=C.indexOf(C.reduce((a,b)=>{return a>b?a:b;}));//找到最先来的是谁。
						// debugger;
						M[i-1].forEach((element,indx) => {
								M[i].splice(indx,1,element);
						});
						M[i].splice(x,1,p);
						C.forEach((e,idx)=>{
								C.splice(idx,1,e+1);
						});
						C.splice(x,1,1);//与此同时被替换的位置则重置为1。
			}

		}
	});

	M.forEach((element,index) => {
			// debugger;
			M[index].forEach((e,i)=>{
				console.log(e);
				document.getElementById('result3').innerHTML="<p>["+M+"]</p><br/><p>缺页率:"+(Plist.length-pointPage)/Plist.length+"</p>";//这里用innerHTML最后会被覆盖
			})
			
		});	
}

</script>
</html>
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值