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閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容

  • JUnit單元測試: 1.什么是單元測試:我們在完成一個項目后,需要對其代碼邏輯進行簡單的全方面的測試,看看代碼邏...
    凱哥學堂閱讀 375評論 0 0
  • 1 喜歡看我個人微信公眾號“秋葉大叔”的朋友常常這樣留言:大叔,我又被你套路了。沒辦法,我就是套路多,層出不窮,花...
    秋葉大叔閱讀 687評論 2 6
  • 下午2點半,組織了關于賣場營運主管訓練營員工管理課程討論會。由于上次供應商管理討論會召開的一般,后期案例提報也一般...
    西貝悠哉閱讀 186評論 0 0