1. 程式人生 > >最近最少使用佇列演算法

最近最少使用佇列演算法

定義:

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

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

實現程式碼:長度為5的佇列

package codeGenerate;
import java.util.ArrayList;  
import java.util.List;  
public class LRU {  
    /** 
     * 記憶體塊的個數 
     */  
    public static final int N = 5;  
    /** 
     * 記憶體塊陣列 
     */  
    Object[] array = new Object[N];  
    private int size;  
      
    public LRU() {  
    }  
    /** 
     * 判斷記憶體區是否為空 
     * @return 
     */  
    public boolean isEmpty() {  
        if(size == 0) {  
            return true;  
        } else {  
            return false;  
        }  
    }  
    /** 
     * 判斷記憶體區是否達到最大值 
     * @return 
     */  
    public boolean isOutOfBoundary() {  
        if(size >=N) {  
            return true;  
        } else {  
            return false;  
        }  
    }  
    /** 
     * 查詢元素o在陣列中的位置 
     * @param o 
     * @return 
     */  
    public int indexOfElement(Object o) {  
        for(int i=0; i<N; i++) {   
            if(o == array[i]) {  
                return i;  
            }  
        }  
        return -1;  
    }     
    /** 
     * 有新的資料o需要申請記憶體 
     * @param o 
     * @return 移出記憶體區的資料 
     */  
    public Object push(Object o) {  
        int t = -1;  
        if(!isOutOfBoundary() && indexOfElement(o) == -1){  
            array[size] = o;  
            size ++;  
        } else if(isOutOfBoundary() && indexOfElement(o) == -1){  
            for(int i=0; i<size-1; i++) {  
                array[i] = array[i+1];                
            }  
            array[size-1] = o;  
        } else {  
            t = indexOfElement(o);  
            for(int i=t; i<size-1; i++) {  
                array[i] = array[i+1];  
            }  
            array[size-1] = o;  
        }  
        if( -1 == t) {  
            return null;  
        } else {  
            return array[t];  
        }  
    }  
    /** 
     * 輸出記憶體區中的各資料 
     */  
    public void showMemoryBlock() {  
        for(int i=0; i<size; i++) {  
            System.out.print(array[i] + "\t");  
        }  
    }  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        Integer iter[] = {4,7,0,7,1,0,1,2,1,2,6};  
        LRU lru = new LRU();  
        for(int i=0; i<iter.length; i++) { 
        System.out.println("當前元素:"+iter[i]);;
            lru.push(iter[i]);  
            lru.showMemoryBlock();  
            System.out.println();  
        }  
    }  
  
}

使用場景:

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