LruCache源码分析
LRU(Least Recently Used)是一种很常用的资源调度策略,与20/80原则契合,在资源达到上限时倾向保留最近经常访问的资源对象。
Android中基于LRU实现了缓存对象,即LruCache,有两处实现:分别为android.support.v4.util.LruCache和android.util.LruCache,其中前者的设计符合Lru,
后者在资源不足时清除的最近经常访问的资源对象,使用时,需要注意这点,此处分析android.support.v4.util.LruCache的源码。
LruCache是一个范型类,其类图如下:
可以看出LruCache是基于LinkedHashMap的,LinkedHashMap不是线程安全的,所以LruCache通过monitor方式,api上(内)对LruCahce对象
其中accessOrder非常重要,若为true,则链表的head->tail的顺序为"最近最少访问->最近经常访问",即当访问某个对象时,会将其插入到tail后,
作为新tail,若accessOrder为false,则在访问时不会移动访问对象的位置。accessOrder=true才符号LruCache的设计要求。
LruCache中的size含义很灵活,LruCache使用者可根据业务需求来定义,比如创建的是一个Bitmap缓存,如LruCache<String, Bitmap>,
这个size可以表示缓存中Bitmap的总大小(单位kb),LruCache提供了计算size的函数,调用者可在LruCache子类中重写来定义,但是需要保持其含义(单位)与
maxSize一致,比如:
下面简要分析下LruCache.get和put,其中get和put都在内部使用map时上锁,get核心代码如下:
可以看到, LruCache是不允许key为null的,当存在key对应的value时,直接返回,此处LinkedHashMap.get操作
会将value挪到tail上,实现如下:
可以看到LinkedHashMap是一个双向循环链表,再来看看put操作:
trimToSize的核心实现如下:
可以看到清理的是head指向的item,即最近最少使用的item,而android.util.LruCache的trimToSize清理的是tail:
总结如下:
2.Android中存在两个LruCache,使用support-v4包里的
3.LruCache基于LinkedHashMap的线程安全类,通过锁实现,最近访问的资源对象放到tail是通过LinkedHashMap.get实现
,资源回收是在put中实现。
4.LruCache子类一般需要重写sizeOf,定义缓存中的size
LruCache源码分析的更多相关文章
- MyBatis源码分析(3)—— Cache接口以及实现
@(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...
- Volley源码分析(2)----ImageLoader
一:imageLoader 先来看看如何使用imageloader: public void showImg(View view){ ImageView imageView = (ImageView) ...
- druid 源码分析与学习(含详细监控设计思路的彩蛋)(转)
原文路径:http://herman-liu76.iteye.com/blog/2308563 Druid是阿里巴巴公司的数据库连接池工具,昨天突然想学习一下阿里的druid源码,于是下载下来分析了 ...
- Solr4.8.0源码分析(19)之缓存机制(二)
Solr4.8.0源码分析(19)之缓存机制(二) 前文<Solr4.8.0源码分析(18)之缓存机制(一)>介绍了Solr缓存的生命周期,重点介绍了Solr缓存的warn过程.本节将更深 ...
- Solr4.8.0源码分析(18)之缓存机制(一)
Solr4.8.0源码分析(18)之缓存机制(一) 前文在介绍commit的时候具体介绍了getSearcher()的实现,并提到了Solr的预热warn.那么本文开始将详细来学习下Solr的缓存机制 ...
- JDK源码分析(9)之 WeakHashMap 相关
平时我们使用最多的数据结构肯定是 HashMap,但是在使用的时候我们必须知道每个键值对的生命周期,并且手动清除它:但是如果我们不是很清楚它的生命周期,这时候就比较麻烦:通常有这样几种处理方式: 由一 ...
- JDK源码分析(6)之 LinkedHashMap 相关
LinkedHashMap实质是HashMap+LinkedList,提供了顺序访问的功能:所以在看这篇博客之前最好先看一下我之前的两篇博客,HashMap 相关 和 LinkedList 相关: 一 ...
- MyBatis 源码分析系列文章合集
1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章 ...
- mybatis源码分析(三)------------映射文件的解析
本篇文章主要讲解映射文件的解析过程 Mapper映射文件有哪几种配置方式呢?看下面的代码: <!-- 映射文件 --> <mappers> <!-- 通过resource ...
随机推荐
- 2018.07.06 BZOJ 1588: HNOI2002营业额统计(非旋treap)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...
- test 测试spring容器类
- Django入门与实践-第11章:URL 分发(完结)
http://127.0.0.1:8000http://127.0.0.1:8000/boards/1/http://127.0.0.1:8000/boards/2/http://127.0.0.1: ...
- Asp.net mvc验证用户登录之Forms实现
这里我们采用asp.net mvc 自带的AuthorizeAttribute过滤器验证用户的身份,也可以使用自定义过滤器,步骤都是一样. 第一步:创建asp.net mvc项目, 在项目的App_S ...
- Scala类型检查与转换
Scala类型检查与转换 isInstanceOf:检查某个对象是否属于某个给定的类. asInstanceOf:将引用转换为子类的引用. classOf:如果想测试p指向的是一个Employee对象 ...
- hdu 5038 求出现次数最多的grade
http://acm.hdu.edu.cn/showproblem.php?pid=5038 模拟水题 求出现次数最多的grade.如果有多个grade出现的次数一样多,且还有其他的grade,则把这 ...
- 结对编程-四则运算生成器(java实现)
结对伙伴:陈振华 项目要求 1.题目:实现一个自动生成小学四则运算题目的命令行程序. 2.需求: 1. 使用 -n 参数控制生成题目的个数 2. 使用 -r 参数控制题目中数值(自然数.真分数和真 ...
- mssql内存表
自MSSQL2014开始引入内存表. 怎样创建内存表: USE testGO ALTER DATABASE testADD FILEGROUP fg_test CONTAINS MEMORY_OPTI ...
- [翻译]NUnit---Sequential and SetCulture and SetUICulture Attributes(十八)
Sequential特性用于在测试用例上指定NUnit通过为测试提供的参数选择单一值生产测试用例,并且不会生产额外的组合. Note:如果参数数据由多个特性提供,那么NUnit使用数据项的顺序是随机的 ...
- ADO.NET操作PostgreSQL:数据库操作类(已封装)
1.增.删.改通用方法 /// <summary> /// 增.删.改通用方法 /// </summary> /// <param name="commandT ...