老汉谈——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;
                }
    
            };
        }
    }
    
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章