LruCache源码分析
来源:互联网 发布:淘宝主播super米娜华少 编辑:程序博客网 时间:2024/06/01 10:10
1, 概念
Lru的全称是Least Recently Used,近期最少使用的; Cache是缓存的意思。
LruCache 的实现原理:把近期最少使用的数据从缓存中移除,保留使用最频繁的数据。LruCache 主要是利用LinkedHashMap这一数据结构来实现的。LruCache在android系统中应用广泛。
本文分析的LruCache路径:frameworks/base/core/java/android/util/LruCache.java
LruCache变量如下,
private final LinkedHashMap<K, V> map; //当前缓存的值private int size; // 元素个数private int maxSize; //最大值 private int putCount; //添加到缓存中的个数private int createCount; //创建的个数private int evictionCount; //被移除的个数private int hitCount; //正确获取个数private int missCount; //丢失个数
2, LruCache
首先看LruCache的构造方法,仅有一个构造方法,
public LruCache(int maxSize) { if (maxSize <= 0) { throw new IllegalArgumentException("maxSize <= 0"); } this.maxSize = maxSize; this.map = new LinkedHashMap<K, V>(0, 0.75f, true); }
WifiStateMachine中构造了一个大小为160的LruCache
private static final int SCAN_RESULT_CACHE_SIZE = 160;private final LruCache<NetworkDetail, ScanDetail> mScanResultCache;mScanResultCache = new LruCache<>(SCAN_RESULT_CACHE_SIZE);
2.1 put方法
源码如下,
public final V put(K key, V value) { if (key == null || value == null) { // 不能添加为空的元素 throw new NullPointerException("key == null || value == null"); } V previous; synchronized (this) { putCount++; size += safeSizeOf(key, value); // 其实加1 previous = map.put(key, value); if (previous != null) { //在key值和哈希号相同的情况下才不为null,这时候只是替换 size -= safeSizeOf(key, previous); } } if (previous != null) { entryRemoved(false, key, previous, value); // 这个方法在此没有实际意义。 } trimToSize(maxSize); // 调整结构 return previous; }
添加元素主要分为2步骤,
1,调用map的put方法添加
2,调用trimToSize方法调整结构.
2.2 trimToSize方法
public void trimToSize(int maxSize) { while (true) { K key; V value; synchronized (this) { if (size < 0 || (map.isEmpty() && size != 0)) { throw new IllegalStateException(getClass().getName() + ".sizeOf() is reporting inconsistent results!"); } if (size <= maxSize) { // 如果size还未到阈值,就没必要调整 break; } Map.Entry<K, V> toEvict = map.eldest(); // 获取最不频繁的元素 if (toEvict == null) { break; } key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); // 移除 size -= safeSizeOf(key, value); evictionCount++; } entryRemoved(true, key, value, null); } }
主要三个步骤,
1,判断size是否到阈值,决定是否调整元素。
2,依次调用map 的eldest方法获取最不频繁的元素
Map的内部是一个双向列表,所以直接返回链表最后一个元素就可以了,双向链表的效率高。如果是单向链表的话,还要一直查找到最后,效率很低。
Get方法就挺简单的。
3, 小结
1、LruCache 是基于 Lru算法实现的一种缓存机制;
2、Lru算法的原理是把近期最少使用的数据给移除掉,当然前提是当前数据的量大于设定的最大值。
3、LruCache 没有真正的释放内存,只是从 Map中移除掉数据,真正释放内存还是要用户手动释放。
0 0
- android LRUCache源码分析
- LruCache源码分析
- Lrucache源码分析
- LruCache源码分析
- LruCache源码分析
- Android LruCache 源码分析
- LruCache源码分析
- LruCache 源码分析
- LruCache源码分析及思考
- Android SupportV4 LruCache源码分析
- 【Java源码分析】Android-LruCache源码分析
- levelDB源码分析-Cache(LRUCache、HashTable)
- Android中LruCache的源码分析
- 从HashMap到LruCache的源码分析
- Android LruCache 缓存 类 源码 注解 分析
- 从HashMap到LruCache的源码分析
- Android缓存源码分析(DiskLruCache,LruCache)
- Android之LruCache使用和源码分析
- 小程序之用户事件
- Docker网络原则入门:EXPOSE,-p,-P,-link
- Android编程常见问题之五
- 个人常用网站总结
- SVG(可缩放矢量图形)基本图形绘制方法与path路径命令
- LruCache源码分析
- PAT-B 1059. C语言竞赛
- scrapy爬虫整理的一些知识点
- 基于C++11 CPU多线程的 奇偶排序(没有CUDA)
- 十进制转16进制字符
- Java基本数据类型
- 希尔排序(加强版的直接插入排序)
- 从零开始学习Java——基础知识之运算符(第二天)
- 文章标题