- LRU是常用的缓存淘汰策略。缓存的“热度”可以看作是没有访问该缓存的时间,所以会维护一个有序列表,每次访问缓存时,将访问的缓存移动到最前面。当超过容量限制后,删除最久没有被访问的。
- LRU有一些问题,比如如果某个缓存只是偶尔被访问,那也可能再某个情况下,它恰好之前刚被访问一次,导致他不会被删除。所以有改进的方法LFU,LFU还会维护访问次数。
- Redis中使用的是近似的LRU,因为LRU会造成大量的空间消耗。Redis通过维护前一次访问时间,每次随机选择几个,删除最久未被访问的,重复采样知道满足内存要求。
- 通过LeetCode 146,简单实现一下:
- LinkedList + HashMap
class LRUCache { private int capacity; private LinkedList<Integer> list; private HashMap<Integer,Integer>map; public LRUCache(int capacity) { this.capacity = capacity; list = new LinkedList<>(); map = new HashMap<>(); } public int get(int key) { if(map.containsKey(key)){ list.remove(new Integer(key)); list.addFirst(key); return map.get(key); }else{ return -1; } } public void put(int key, int value) { if(map.containsKey(key)){ list.remove(new Integer(key)); }else{ if(capacity<=map.size()){ Integer last = list.pollLast(); map.remove(last); } } list.addFirst(key); map.put(key,value); } } /** * Your LRUCache object will be instantiated and called as such: * LRUCache obj = new LRUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */
- LinkedHashMap:快了很多
class LRUCache extends LinkedHashMap<Integer,Integer>{ private int capacity; public LRUCache(int capacity) { super(capacity,0.75F,true); this.capacity = capacity; } public int get(int key) { return super.getOrDefault(key,-1); } public void put(int key, int value) { super.put(key,value); } @Override protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) { return this.capacity < size(); } }
LRU的简单实现
最新推荐文章于 2022-11-01 23:11:16 发布