1. 程式人生 > >LRU演算法,最近最少使用演算法

LRU演算法,最近最少使用演算法

LRULeast Recently Used的縮寫,即最近最少使用頁面置換演算法,是為虛擬頁式儲存管理服務的,是根據頁面調入記憶體後的使用情況進行決策了。由於無法預測各頁面將來的使用情況,只能利用“最近的過去”作為“最近的將來”的近似,因此,LRU演算法就是將最近最久未使用的頁面予以淘汰。

可以用一個特殊的棧來儲存當前正在使用的各個頁面的頁面號。當一個新的程序訪問某頁面時,便將該頁面號壓入棧頂,其他的頁面號往棧底移,如果記憶體不夠,則將棧底的頁面號移除。這樣,棧頂始終是最新被訪問的頁面的編號,而棧底則是最近最久未訪問的頁面的頁面號。

如輸入以下序列時:4,7,0,7,1,0,1,2,1,2,6

結果為:

4        
4        7        
4        7        0        
4        0        7        
4        0        7        1        
4        7        1        0        
4        7        0        1        
4        7        0        1        2        
4        7        0        2        1        
4        7        0        1        2        
7        0        1        2        6        


java程式碼實現LRU演算法如下:

[java] view plaincopyprint?
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3. publicclass LRU {  
  4.     /** 
  5.      * 記憶體塊的個數 
  6.      */
  7.     publicstaticfinalint N = 5;  
  8.     /** 
  9.      * 記憶體塊陣列 
  10.      */
  11.     Object[] array = new Object[N];  
  12.     privateint size;  
  13.     public
     LRU() {  
  14.     }  
  15.     /** 
  16.      * 判斷記憶體區是否為空 
  17.      * @return 
  18.      */
  19.     publicboolean isEmpty() {  
  20.         if(size == 0) {  
  21.             returntrue;  
  22.         } else {  
  23.             returnfalse;  
  24.         }  
  25.     }  
  26.     /** 
  27.      * 判斷記憶體區是否達到最大值 
  28.      * @return 
  29.      */
  30.     publicboolean isOutOfBoundary() {  
  31.         if(size >=N) {  
  32.             returntrue;  
  33.         } else {  
  34.             returnfalse;  
  35.         }  
  36.     }  
  37.     /** 
  38.      * 查詢元素o在陣列中的位置 
  39.      * @param o 
  40.      * @return 
  41.      */
  42.     publicint indexOfElement(Object o) {  
  43.         for(int i=0; i<N; i++) {   
  44.             if(o == array[i]) {  
  45.                 return i;  
  46.             }  
  47.         }  
  48.         return -1;  
  49.     }     
  50.     /** 
  51.      * 有新的資料o需要申請記憶體 
  52.      * @param o 
  53.      * @return 移出記憶體區的資料 
  54.      */
  55.     public Object push(Object o) {  
  56.         int t = -1;  
  57.         if(!isOutOfBoundary() && indexOfElement(o) == -1){  
  58.             array[size] = o;  
  59.             size ++;  
  60.         } elseif(isOutOfBoundary() && indexOfElement(o) == -1){  
  61.             for(int i=0; i<size-1; i++) {  
  62.                 array[i] = array[i+1];                
  63.             }  
  64.             array[size-1] = o;  
  65.         } else {  
  66.             t = indexOfElement(o);  
  67.             for(int i=t; i<size-1; i++) {  
  68.                 array[i] = array[i+1];  
  69.             }  
  70.             array[size-1] = o;  
  71.         }  
  72.         if( -1 == t) {  
  73.             returnnull;  
  74.         } else {  
  75.             return array[t];  
  76.         }  
  77.     }  
  78.     /** 
  79.      * 輸出記憶體區中的各資料 
  80.      */
  81.     publicvoid showMemoryBlock() {  
  82.         for(int i=0; i<size; i++) {  
  83.             System.out.print(array[i] + "\t");  
  84.         }  
  85.     }  
  86.     /** 
  87.      * @param args 
  88.      */
  89.     publicstaticvoid main(String[] args) {  
  90.         Integer iter[] = {4,7,0,7,1,0,1,2,1,2,6};  
  91.         LRU lru = new LRU();  
  92.         for(int i=0; i<iter.length; i++) {  
  93.             lru.push(iter[i]);  
  94.             lru.showMemoryBlock();  
  95.             System.out.println();  
  96.         }  
  97.     }  
  98. }  

        LRU演算法也可以用於一些實際的應用中,如你要做一個瀏覽器,或類似於淘寶客戶端的應用的就要用到這個原理。大家都知道瀏覽器在瀏覽網頁的時候會把下載的圖片臨時儲存在本機的一個資料夾裡,下次再訪問時就會,直接從本機臨時資料夾裡讀取。但儲存圖片的臨時資料夾是有一定容量限制的,如果你瀏覽的網頁太多,就會一些你最不常使用的影象刪除掉,只保留最近最久使用的一些圖片。這時就可以用到LRU演算法 了,這時上面演算法裡的這個特殊的棧就不是儲存頁面的序號了,而是每個圖片的序號或大小;所以上面這個棧的元素都用Object類來表示,這樣的話這個棧就可以儲存的對像了。