java实现页面替换算法(LRU、LFU、FIFO)

34.jpg
34.jpg

缓存算法(淘汰算法),常见算法有LRU、LFU和FIFO等算法,每种算法各有各的优势和缺点及适应环境。

PAGE REPLACEMENT POLICIES

  • When page fault occurs, the referenced page must be loaded.
  • If there is no available frame in memory, then one page is selected for replacement.
  • If the selected page has been modified, it must be copied back to disk (swapped out).
  • A page replacement algorithm is said to satisfy the inclusion property or is called a stack algorithm if the set of pages in an n-frame memory is always a subset of the pages in a(n + 1) frame memory.

FIFO (First IN, First OUT)

  • FIFO implements a queue.
  • A FIFO replacement algorithm links with each page the time when that page was added into the memory
  • The oldest page is chosen when a page is going to be replaced. We can create a FIFO queue to hold all the pages present in the memory disk. At the head of the queue we replace the page. We insert page at the tail of the queue when a page is added into the memory disk.
  • Implementation:

1.Two arrays, page[n] and frame[f_size] (queue), where n is the number of pages and f_size is the size of the frame buffer
2.When there is page fault, it replaces the page in the frame after the previously replaced frame

LRU (Least Recently Used)

  • On a page fault, the frame that was least recently used is replaced.
  • Implementation:

1.Two arrays, page[n] and frame[f_size] (queue), where n is the number of pages and f_size is the size of the frame buffer
2.Two additional arrays, a[f_size] & b[f_size], where a[] stores the sorted list of pages from most recently used to least recently used and b is the temporary array used to update the list
3.When page fault occurs, it finds the index of the LRU from frame[] based on the last element of a[] and replaces that page
4.Each time a page is referenced, update a[]

LFU (Least Frequently Used)

  • The page which has the smallest count is going to be replaced. The reason for this selection is that a mostly used page should have a larger reference count.
  • This algorithm suffers from the situation in which a page is used heavily during the staring phase of aprocess, but then is never again. Since it was used heavily, it has a large frequency count and remains in memory even if it is no longer needed.
  • Implemention:

1.Two arrays, page[n] and frame[f_size], where n is the number of pages and f_size is the size of the frame buffer
2.An array cnt[f_size] is used to store and keep track of the tally or frequency of usage of the pages
3.When a page fault occurs, it replaces the page with the least frequency of usage
4.If there are more than 1 page that the least frequency of usage, use FIFO logic and replace the page that came first among those least frequently used pages.

ReplacementPolicy.java

package replacementpolicy;

import java.util.*;

class ReplacementPolicy{

    public static void main(String args[]){

        Scanner scan = new Scanner(System.in);
        int frameSize, page=0, choice, n;                   //Declare variables for: frame size, page, choice, and size n
        String inputString;                                 //String variable for the input string and array of Strings for the pages 
        String pages[];                     
        String frame[];                                     //The array for the frames

        do{
            /* MAIN MENU */
            System.out.println( "====================" );
            System.out.println( "\tMenu" );
            System.out.println(  "====================") ;
            System.out.println("\t1.FIFO" );
            System.out.println( "\t2.LRU" );
            System.out.println( "\t3.LFU" );
            System.out.println( "\t4.EXIT" );

            /* Input Choice */
            do {
                System.out.println( "Enter your choice: " );
                while ( !scan.hasNextInt() ) {
                    System.out.println( "Your input is invalid. The choices are 1, 2, 3 and 4 only." );
                    System.out.println("Enter your choice: ");
                    scan.next();
                }
                choice = scan.nextInt();
                if( choice!=1 && choice!=2 && choice!=3 && choice!=4 )
                {
                    System.out.println("Your input is invalid. The choices are 1, 2, 3 and 4 only. Enter Again.");
                }
            }while (choice!=1 && choice!=2 && choice!=3 && choice!=4);

            /* EXIT if input choice is 4*/
            if( choice == 4 ){
                System.out.println( "*****************************" );
                System.out.println( "  You chose to EXIT. Bye! :)" );
                System.out.println( "*****************************" );
                break;
            }
            /* Input Number of Pages */
            do {                                                                        //while input is not a positive integer, asks for input
                System.out.println( "Enter the number of pages: " );
                while ( !scan.hasNextInt() ) {                                          //checks if input is not an integer
                    System.out.println( "Please enter an integer." );                       //displays error message
                    scan.next();
                }
                n = scan.nextInt();                                                     //gets number of pages input
                if( n <= 0 ){
                    System.out.println( "Please enter a positive integer." );   //checks if input is not positive
                }                                                               //displays error message
                                                                                
            } while ( n <= 0 );
            
            pages = new String[n];                                                      //allocates memory for n number of Strings

            /* Input the Reference String separated by  "\\s+" or space */
            System.out.println( "Enter Reference String (must be separated by space): " );
            scan.nextLine();
            do{                                                                         //while length of pages[] array is not equal to n, asks for input
                inputString = scan.nextLine();                                          //gets the input string
                pages = inputString.split( "\\s+" );                                        //splits the string into substrings separated by space and store in the pages[] array
                if( pages.length != n ){                                                    //checks if the number of pages entered is equal to n
                    System.out.println( "The number of pages in your input string is not " + n + ". It is " + pages.length + ". Please enter string again." ); //displays error message
                }
            }while( pages.length != n );

            /* Input the Number of Frames */
            do {                                                                        //while input is not a positive integer, asks for input
                System.out.println( "Enter Number of Frames: " );
                while ( !scan.hasNextInt() ) {                                          //checks if input is not an integer
                    System.out.println( "Please enter an integer." );   //displays error message
                    scan.next();
                }
                frameSize = scan.nextInt();                                             //gets frame buffer size input
                if( frameSize <= 0) {
                    System.out.println( "Please enter a positive integer." );   //checks if input is not positive
                                                                            //displays error message
                }                                               
                            
            }while ( frameSize <= 0 );

            frame = new String[ frameSize ];                                                    //string array frame[] of frameSize
            for( int i = 0; i < frameSize; i++ ){                                                   //initializes frame array with " " which indicates an empty frame array
                frame[i]=" ";
            }

            /* Display the data inputed */
            System.out.println( "The size of input string: " + n );
            System.out.println( "The input string: " + inputString );
            System.out.println( "The Number of Frames: " + frameSize + "\n" );
            System.out.println( "pages array: " );

            for (int i = 0; i < pages.length ; i++) {
                System.out.println("index " + "[" + i + "]: " + pages[i]);  
            }
            System.out.println("\n");

            /* Perform FIFO page replacement */
            if( choice == 1 ){
                System.out.println( "************************" );
                System.out.println( "\tFIFO" );
                System.out.println( "************************" );
                FIFO(n, pages, frame);
            }

            /* Perform LRU page replacement */
            if( choice == 2 ){
                System.out.println( "************************" );
                System.out.println( "\tLRU" );
                System.out.println( "************************" );
                LRU( n, pages, frame, frameSize );
            }

            /* Perform LFU page replacement */
            if( choice == 3 ){
                System.out.println( "************************" );
                System.out.println( "\tLFU" );
                System.out.println( "************************" );
                LFU( n, pages, frame, frameSize );
            }
        }while( choice != 4 );
    }

    /* 1. First In First Out (FIFO) */
    public static void FIFO( int n, String pages[], String frame[] ){                       //arguments accept a size n, an array of the pages and the frame array
        String page;
        boolean flag;                                                                   //flag for page fault
        int pageFaultCounter = 0, page_fault = 0;                                           //frame pageFaultCounter; page fault counter
        /* while there are pages */
        for( int pg=0 ; pg < n ; pg++ ){                                                
            page = pages[ pg ];
            flag = true;                                                                //initially, flag is true because it has not yet found a page hit
            for( int j=0 ; j < frame.length ; j++ ){                                        //checks if page hit
                if( frame[j].equals( page ) ){                                              
                    flag = false;                                                       //if page hit, no fault occurs
                    break;
                }
            }
            if( flag ){                                                                 //If there is page fault,
                frame[ pageFaultCounter ] = page;                                       //replace the page in frame[pageFaultCounter].
                pageFaultCounter++;
                if( pageFaultCounter == frame.length ) 
                {
                    pageFaultCounter=0;                    //set pageFaultCounter back to 0 if pageFaultCounter is equal to length of frame
                }                               
                System.out.print( "frame: " );
                /* display the frame buffer array */
                for( int j=0 ; j < frame.length ; j++ )
                {
                    System.out.print( frame[j]+"   " );
                }
                System.out.print( " --> page fault!" );
                System.out.println();
                page_fault++;                                                               //add 1 to the page faults
            }
            else{
                System.out.print( "frame: " );                                          //If page hit, no replacement
                /* diaplay the frame buffer array */                                            
                for( int j=0 ; j < frame.length ; j++ ){
                    System.out.print(frame[j]+"   " );
                }
                System.out.print( " --> page hit!" );
                System.out.println();
            }
        }
        System.out.println( "\nTotal Page Fault/s:" + page_fault + "\n" );                          //Display Total Page Fault
    }

    /* Least Recently Used (LRU) */
    public static void LRU( int n, String pages[], String frame[], int frameSize ){         //arguments accept a size n, an array of the pages, the frame array and frame size
        String page = " ";                                                              //temp page
        boolean flag;                                                                   //flag for page fault
        int k = 0, page_fault = 0;                                                      //index k (if page fault occurs); page fault counter
        String a[] = new String[ frameSize ];                                               /* 2 temporary arrays to keep track of LRU page, sorted from most recent to least recent */
        String b[] = new String[ frameSize ];                                               /* first element of a[] is most recent and the last element is the LRU */
        for(int i = 0 ; i < frameSize ; i++ ){                                                  //initialize array elements to " "
            a[ i ] = " ";
            b[ i ] = " ";
        }

        for( int pg = 0 ; pg < n ; pg++ ){
            page = pages[ pg ];
            flag = true;                                                                //initially, flag is true because it has not yet found a page hit
            for( int j=0 ; j < frameSize ; j++ ){                                           //checks if page hit
                if( frame[ j ].equals( page ) ){                                                
                    flag = false;                                                       //If page hit, no page fault occurs
                    break;
                }
            }
    
            for( int j=0 ; j < frameSize && flag ; j++ ){                                   //While page fault occurs and find the least recently used page,
                if( frame[ j ].equals(a[ frameSize-1 ] ) ){                                     //If least recently used
                    k = j;                                                              //set index to be replaced
                    break;
                }
            }
    
            if( flag ){                                                                 //If page fault,
                frame[ k ] = page;                                                          //replace frame[k] with the page.   
                System.out.print( "frame: " );
                /* display frame buffer array */
                for(int j = 0 ; j < frameSize ; j++)
                    System.out.print( frame[j] + "  " );
                System.out.println( " --> page fault!" );
                page_fault++;                                                               //add 1 to page fault counter
            }
            else{                                                                       //If page hit, no replacement
                /* display frame buffer array */
                System.out.print( "frame: " );
                for( int j=0 ; j < frameSize ; j++ )
                    System.out.print( frame[ j ]+"  " );
                System.out.println( " --> page hit!" );
            }

            int p = 1;                                                                  //counter
            b[ 0 ] = page;                                                                  //first element of b[] is the page (b is most recent)
            /* update MRU-LRU array */
            for( int j=0 ; j < a.length ; j++ ){                                            //while j < size of frames
                if( !page.equals( a[ j ] ) && p < frameSize ) {                                 //the elements in a[] that are not equal to referenced page or is not the most recently used are copied to b[j] from left
                    b[ p ] = a[ j ];                                                            
                    p++;
                }
            }
            for( int j = 0 ; j < frameSize ; j++ ){                                         //set LRU a[] to the updated LRU b[]
                a[ j ] = b[ j ];
            }
        }
        System.out.println( "\nTotal Page Fault/s: "+ page_fault + "\n" );                          //display total page faults
    }

    /* Least Frequently Used (LFU) */
    public static void LFU( int n, String pages[], String frame[], int frameSize ){         //arguments accept a size n, an array of the pages, the frame array and frame size
        int k = 0, page_fault = 0;                                                          //index k for frequency array; page fault countersummarize
        int leastFrequency;                                                                     //for the least frequency
        String page;                                                                    //tempp page
        int Frequency[] = new int[ frameSize ];                                                 //array to store and keep track of frequencies
        boolean flag = true;                                                                //flag for a page fault
        
        /* Initializes the frequency to 0 */
        for(int i = 0 ; i < frameSize ; i++ ){
            Frequency[ i ] = 0;
        }
        /* while there is page */
        for( int pg = 0 ; pg < n ; pg++ ){
            page = pages[ pg ];                                                         //assign temp page = pages[page]
            flag = true;                                                                    //initially, flag is true because it has not yet found a page hit

            for( int j=0 ; j < frameSize ; j++ ){                                           //checks if page hit
                if( page.equals( frame[ j ] ) ){                                                //If page hit, no page fault occurs
                    flag = false;
                    Frequency[ j ]++;                                                           //add 1 to its frequency
                    break;                                                              //break
                }
            }

            if( flag ){                                                                 //If a page hit occurs,
                leastFrequency = Frequency[ 0 ];
                for( int j = 0 ; j < frameSize ; j++ ){                                     //Look for least number of frequency
                    if( Frequency[ j ] < leastFrequency ){
                        leastFrequency = Frequency[ j ];
                        break;
                    }
                }
                for( int j = 0 ; j < frameSize ; j++ ){                                     //Find the page with the least frequency from the left
                    if( leastFrequency == Frequency[ j ] ){                                                 //The left-most page will be the one to be replaced
                        frame[ j ] = page;
                        k = j;
                        break;
                    }
                }
                Frequency[ k ] = 1;                                                             //set the frequency of new page to 1
                System.out.print( "frame: " );
                /* display frame buffer array */
                for( int j = 0 ; j < frameSize ; j++ ){
                    System.out.print( frame[ j ]+"   " );
                    page_fault++;                                                           //add 1 to page fault counter
                }
                System.out.println( " --> Page fault!" );
            }
            else{                                                                       //If page hit, no replacement
                System.out.print( "frame: " );
                /* display frame buffer array */
                for( int j = 0 ; j < frameSize ; j++ )
                    System.out.print( frame[ j ]+"   " ); 
                System.out.print( " --> Page hit!" );
                System.out.println();
            }
        }       
        System.out.println( "\nTotal Page Fault/s: " + page_fault + "\n" );
    }
}

Running Effect

屏幕快照 2017-12-01 10.37.38.png
屏幕快照 2017-12-01 10.37.38.png

屏幕快照 2017-12-01 10.37.50.png
屏幕快照 2017-12-01 10.37.50.png

Source Download

Please click the address:Page Replacement Policy (LRU、LFU、FIFO)

Summarize

评价一个缓存算法好坏的标准主要有两个,一是命中率要高,二是算法要容易实现。当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。LFU效率要优于LRU,且能够避免周期性或者偶发性的操作导致缓存命中率下降的问题。但LFU需要记录数据的历史访问记录,一旦数据访问模式改变,LFU需要更长时间来适用新的访问模式,即:LFU存在历史数据影响将来数据的“缓存污染”效用。FIFO虽然实现很简单,但是命中率很低,实际上也很少使用这种算法。
#个人主页:www.iooy.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • JUnit单元测试: 1.什么是单元测试:我们在完成一个项目后,需要对其代码逻辑进行简单的全方面的测试,看看代码逻...
    凯哥学堂阅读 353评论 0 0
  • 1 喜欢看我个人微信公众号“秋叶大叔”的朋友常常这样留言:大叔,我又被你套路了。没办法,我就是套路多,层出不穷,花...
    秋叶大叔阅读 652评论 2 6
  • 下午2点半,组织了关于卖场营运主管训练营员工管理课程讨论会。由于上次供应商管理讨论会召开的一般,后期案例提报也一般...
    西贝悠哉阅读 161评论 0 0