页面置换算法JAVA

1.OPT最佳页面置换算法

  选择的被淘汰页面,将是以后永久不会使用的 或者在未来最长时间内不会被访问的页面

但是人们目前无法预知未来。因而在算法上难以实现。

为某进程分配三个物理块,页面号引用串:

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

首先装入:

7
0

1

访问页面2时,产生缺页中断。

此时向后看

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

物理块中的7,0,1都在未来将被访问,但是 7是未来最长时间内不会被访问的页面。

因此置换7

2
0

1

 

 2.FIFO先进先出页面置换算法

选择在页面驻留时间最久的页面予以淘汰。

驻留时间最久的怎么找?

我们用队列buffer来模拟物理块

7
0
1

 

 

 当访问2时,产生缺页中断。

利用remove()去掉队首7,把2添加至队尾。

0
1
2

 

 

 

 

可以发现, 页面驻留时间最久的页面在队首,替换进来的新页面添加至队尾。所以驻留时间最久的页面总是在队首。

代码实现:

import java.util.LinkedList;
import java.util.Queue;



public class FIFO {
     Queue<Integer> buffer = new LinkedList<Integer>();
     int arry[]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};
     int block=3;//物理块大小
     int ChangeNum=0;

     void fifo(){
        System.out.println("--------------------FIFO算法---------------------");
        System.out.println("访问序列   ");
        for(int i=0;i<arry.length;i++)
        {
            System.out.print(arry[i]+"   ");
        }
        System.out.println();

        
        for(int i=0;i<=2;i++)
        {
            buffer.add(arry[i]);
        }

        
        show();
        for(int i=block;i<arry.length;i++)
        {
            if(juge(arry[i]))
            {
                System.out.println(arry[i]+"在队列中,无需置换");
                System.out.println();
            }
            else
            {
                //去掉驻留最久的--->队首 buffer.remove()
                System.out.println(arry[i]+"不在队列,移除"+buffer.remove());
                buffer.add(arry[i]);
                ChangeNum++;
                show();
            }
            
        }

     }
    //判断要访问的页面在不在物理块中
    boolean juge(int k){
        Object[] o =buffer.toArray();
        for(int i=0;i<o.length;i++)
        {
            if((int)o[i]==k)
            {
                return true;
            }

        }
        return false;
     }
    //显示现有物理块
     void show(){
        System.out.println("现有队列:");
        Object[] o =buffer.toArray();
        for(int i=0;i<o.length;i++)
        {
            System.out.println(o[i]);
        }
        System.out.println();
     }
     public static void main(String[] args) throws Exception {
        FIFO f = new FIFO();
        f.fifo();
        System.out.println("----------页面置换次数"+f.ChangeNum+"------------");
    }


}

 结果:

--------------------FIFO算法---------------------
访问序列
7   0   1   2   0   3   0   4   2   3   0   3   2   1   2   0   1   7   0   1
现有队列:
7
0
1

2不在队列,移除7
现有队列:
0
1
2

0在队列中,无需置换

3不在队列,移除0
现有队列:
1
2
3

0不在队列,移除1
现有队列:
2
3
0

4不在队列,移除2
现有队列:
3
0
4

2不在队列,移除3
现有队列:
0
4
2

3不在队列,移除0
现有队列:
4
2
3

0不在队列,移除4
现有队列:
2
3
0

3在队列中,无需置换

2在队列中,无需置换

1不在队列,移除2
现有队列:
3
0
1

2不在队列,移除3
现有队列:
0
1
2

0在队列中,无需置换

1在队列中,无需置换

7不在队列,移除0
现有队列:
1
2
7

0不在队列,移除1
现有队列:
2
7
0

1不在队列,移除2
现有队列:
7
0
1

----------页面置换次数12------------

3.LRU最近最久未使用算法。

选择最近最久未使用的页面给予淘汰。

最近最久未使用的页面怎么找?

OPT是看未来(向后看),那么LRU就是回忆过去(向前看),即向前寻找当前物理块中的页面,直至全部找到,最后找到的一个,就是最近最久未使用的页面。

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

首先装入

7
0

1

 

访问页面2:

产生缺页中断。此时向前看 ,7 0 1 2,物理块中的7,0,1全部找到,7是最后找到的,所以7是最近最近未使用的页面。

因此置换7

2
0

1

访问页面0:

0在页面中。不会产生缺页中断,因此不用置换。

访问页面3:

产生缺页中断,向前看。7 0 1 2 0 3,物理块中的2,0,1全部找到,1是最后找到的,所以1是最近最近未使用的页面。

因此置换1

2
0

3

访问页面0:

0在页面中。不会产生缺页中断,因此不用置换。

访问页面4:

产生缺页中断,向前看。7 0 1 2 0 3 0 4,物理块中的2,0,3全部找到,2是最后找到的,所以2是最近最近未使用的页面。

因此置换2

4
0

3

。。。。如此往复

代码实现:

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;



public class LRU {
    int arry[]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};
    
    int block=3;//物理块大小
    int positon=0;//定位请求访问页面的位置
    int ChangeNum=0;

    LinkedList<Integer> stack = new LinkedList<Integer>();
    
    void lru(){
        System.out.println("--------------------LRU算法---------------------");
        System.out.println("访问序列   ");
        for(int i=0;i<arry.length;i++)
        {
            System.out.print(arry[i]+"   ");
        }
        System.out.println();

        //装载初始三个页面 7 0 1
        for(int i=0;i<=2;i++)
        {
            stack.add(arry[i]);
            positon++;
        }

        show();
        for(int i=positon;i<arry.length;i++)
        {
            if(juge(arry[i]))
            {
                positon++;
                System.out.println(arry[i]+"在页面中,无需置换");
                System.out.println();
                
            }
            else
            {
                
                int m=change();
                System.out.println(arry[i]+"不在页面中,移除"+arry[m]);
                stack.remove((Integer)arry[m]);//如果只写arry[m]  就删除下标为m的 产生错误
                stack.add(arry[i]);
                show();
                positon++;
                ChangeNum++;
            }

            
        }
    }

    //判断页面是被包含
    boolean juge(int k){
        if(stack.contains(k))
        {
            return true;
        }
        return false;
     }

    void show(){
        System.out.println("现有页面:");
        for(int i=0;i<stack.size() ;i++)
        {
            System.out.println(stack.get(i));
        }
        System.out.println();
     }

    //找到要替换页面的位置
     int change(){
        Set<Integer> s = new HashSet<Integer>();
        int k = positon-1;
        while(s.size()<3)
        {
            
            s.add(arry[k]);
            k--;
        }
        return k+1;
     }


     public static void main(String[] args) {
        LRU l  =new LRU();
        l.lru();
        System.out.println("----------页面置换次数"+l.ChangeNum+"------------");
     }


}

    此处难点在于向前看的时候,怎么确定物理块中的元素全部找到时,谁是最后找到的。

如果简单的只判断找到三个元素。

7 0 1 2 0 3 0 4,那么,0是最后找到的,所以0是最近最近未使用的页面。产生错误。

所以可以利用集合,集合中的元素是唯一的。只要判断集合长度>3,此时取出元素即可。

对应代码:

    //找到要替换页面的位置
     int change(){
        Set<Integer> s = new HashSet<Integer>();
        int k = positon-1;
        while(s.size()<3)
        {
            
            s.add(arry[k]);
            k--;
        }
        return k+1;
     }

结果:

--------------------LRU算法---------------------
访问序列
7   0   1   2   0   3   0   4   2   3   0   3   2   1   2   0   1   7   0   1
现有页面:
7
0
1

2不在页面中,移除7
现有页面:
0
1
2

0在页面中,无需置换

3不在页面中,移除1
现有页面:
0
2
3

0在页面中,无需置换

4不在页面中,移除2
现有页面:
0
3
4

2不在页面中,移除3
现有页面:
0
4
2

3不在页面中,移除0
现有页面:
4
2
3

0不在页面中,移除4
现有页面:
2
3
0

3在页面中,无需置换

2在页面中,无需置换

1不在页面中,移除0
现有页面:
2
3
1

2在页面中,无需置换

0不在页面中,移除3
现有页面:
2
1
0

1在页面中,无需置换

7不在页面中,移除2
现有页面:
1
0
7

0在页面中,无需置换

1在页面中,无需置换

----------页面置换次数9------------

好的,over

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
页面置换算法是操作系统中用于管理内存的一种重要技术,它决定了在物理内存不够用时,将哪些页面从内存中调出,以便为新的页面腾出空间。常见的页面置换算法有以下几种: 1. 最佳适应算法(Optimal Algorithm):该算法是一种最理想的页面置换算法,它总是选择未来最长时间内不再被引用的页面进行置换。然而,由于无法预测未来的页面访问情况,实际中无法实现。 2. 先进先出算法(FIFO Algorithm):该算法是最简单的页面置换算法,它总是选择最早进入内存的页面进行置换。缺点是存在"Belady异常",即内存分配增加时,缺页中断反而会增加。 3. 最近最久未使用算法(LRU Algorithm):该算法是一种基于"局部性原理"的页面置换算法,它总是选择最近最久未使用的页面进行置换。这种算法较好地利用了程序的局部性特征,但实现较为复杂。 4. 时钟置换算法(Clock Algorithm):该算法基于环形链表实现,每个页面对应一个标志位。当页面被访问时,标志位置1;当需要置换页面时,从当前位置开始,找到第一个标志位为0的页面进行置换。如果找不到标志位为0的页面,则将所有标志位置为0,并再次进行搜索。 5. 最不常用算法(LFU Algorithm):该算法根据页面被访问的频率进行置换,总是选择使用次数最少的页面进行置换。这种算法适用于频繁访问某些页面的场景。 以上是常见的页面置换算法,每种算法都有其优缺点,选择哪种算法取决于具体应用场景和需求。在Java中,你可以根据需要实现这些算法,并应用于你的项目中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值