老漢談——LRU方案

含義

LRU,全程Least Recently Used, 最近最少使用的,也是最近最久沒有使用的意思。一般用在內存淘汰策略裏。如Redis的內存淘汰機制。

設計原則

如果一個內存最近一直沒有使用,那麼它的訪問概率就會很低,當內存空間快滿的時候,就應該把這些最近最近很久沒有反問的數據給淘汰掉。

工作原理

  • 操作系統教程裏的LRU工作原理:頁置換算法。

    該算法的思路是,發生缺頁中斷時,選擇未使用時間最長的頁面置換出去

  • 假如內存按照棧的方式訪問,棧頂是最遠使用的,棧底是最近使用的,滿足棧的先進後出原則。

  • 分別往棧插入1、2、3,當插入4已滿,而且大於4就要開始淘汰最近很久沒有使用的數據。所以插入5,就要開始從最底層刪除3,

    頂層插入5,變成第三個步驟的5、4、3、2,其他以次類推。但下圖的最後插入5時,因爲之前存在5,所以直接把原來的給刪除後,再從頂層插入5就不一樣。具體可以參考下圖。
    在這裏插入圖片描述

實現方式

  • 數組

    插入的數據存放到數組裏,並且插入的元素標記個訪問的時間戳,每次插入數組元素時,自己的時間戳爲0,其他元素的時間戳+1,

    當訪問元素時,被訪問元素的時間戳置爲0. 插入、刪除的時間複雜度都是O(n)。

  • 鏈表

    每次插入的數據存放到鏈表的頭部,每次訪問且命中數據,則移到頭部,但鏈表容量滿的時候,移除鏈表尾部數據。時間複雜度O(n)。

  • 雙鏈表+HashMap
    在這裏插入圖片描述

  • 訪問和插入方式和鏈表一樣,只是Map的Value指向的是鏈表的Node點的V,這樣可以快速定位,時間複雜度O(1)。

    LinkedHashMap是最適合實現LRU的數據結構。HashMap有個抽象方法removeEldestEntry方法,本身沒有任何實現,按LinedHashMap重寫了這個方法(如下)

    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
            return false;
        }
    

    這樣,我們可以自己重寫這個方法,定義淘汰策略。

  • JAVA代碼如下:https://github.com/zhanshenzhi2008/orjrs_jdk/blob/master/src/main/java/com/orjrs/jdk/lru/LinkedHashMapLru.java

    package com.orjrs.jdk.lru;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * 線性列表實現LRU(Least Recently Used)
     *
     * @author orjrs
     * @create 2020-05-24 08:49
     * @since 1.0.0
     */
    public class LinkedHashMapLru<K, V> {
    
        /** 雙鏈表HashMap */
        private LinkedHashMap<K, V> linkedHashMap;
    
        /** map */
        private static final float THRSHOLD = 0.75f;
    
        /** 緩存大小 */
        private int cacheSize;
    
    
        public void LinkedLru(int cacheSize) {
            int capacity = (int) Math.ceil(cacheSize * THRSHOLD);
            linkedHashMap = new LinkedHashMap<K, V>(capacity, THRSHOLD, true) {
                @Override
                protected boolean removeEldestEntry(Map.Entry eldest) {
                    return size() > LinkedHashMapLru.this.cacheSize;
                }
    
            };
        }
    }
    
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章