Android开源项目 Universal imageloader 源码研究之Lru算法
https://github.com/nostra13/Android-Universal-Image-Loader
universal imageloader 源码研究之Lru算法
LRU - Least Recently Used 最近最少使用算法
字面意思就是在数据队列里面 最少使用的优先移除,腾出空间 提高任务调度,
接口
com.nostra13.universalimageloader.cache.memory.MemoryCache
实现
com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache
上面的是内存中最近最少使用的数据 将会移除从内存中。
通过 com.nostra13.universalimageloader.core.ImageLoaderConfiguration 可以设置cacheSize
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(context)
.memoryCacheSize(10 * 1024 * 1024) // 10MB 大小
.build();
ImageLoader imageloader = ImageLoader.getInstance();
imageloader.init(configuration);
如果客户端没有主动设置cacheSize 将会创建一个默认的大小
com.nostra13.universalimageloader.core.DefaultConfigurationFactory
public static MemoryCache createMemoryCache(Context context, int memoryCacheSize) {
if (memoryCacheSize == 0) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass(); //这个返回一个APK的heap最大值限制
if (hasHoneycomb() && isLargeHeap(context)) {
memoryClass = getLargeMemoryClass(am);
}
memoryCacheSize = 1024 * 1024 * memoryClass / 8; // 取 1/8 大小内存, 如果是128MB cacheSize为16MB大小
}
return new LruMemoryCache(memoryCacheSize);
}
// am.getMemoryClass(); 我的PAD打印是128MB
static public int staticGetMemoryClass() {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", "");
if (vmHeapSize != null && !"".equals(vmHeapSize)) {
return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
}
return staticGetLargeMemoryClass();
}
看看 LruMemoryCache
public LruMemoryCache(int maxSize) { //初始化大小
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<String, Bitmap>(0, 0.75f, true); //LinkedHashMap 数据结构
//注意 第三个参数为true表示 每次执行put和get会把对应的Entry移到最新位置,如果设置为false 位置不会变化 会导致移除的对象为第一个put的对象
/**
* 比如顺序: put(01,bitmap), put(02,bitmap) put(03,bitmap) put(01,bitmap)
* 如果设置为true会移除掉 key=02的数据
* 如果设置为false会移除掉key=01的数据,但是01的数据 最后又更新了,显然不符合LRU的特点
* 如果调用了get方法 也会把item位置更新到最新,这样没有被调用的数据 就排在最后 可能会被移除掉
* MAP 迭代的话 第一个元素就是 最少使用的对象
*/
}
public final boolean put(String key, Bitmap value) {
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
} synchronized (this) {
size += sizeOf(key, value); //开始计算大小
Bitmap previous = map.put(key, value); //之前有重复的key 取出对象 ,put函数返回上次已经存储key对应的值
if (previous != null) {
size -= sizeOf(key, previous); //减去以前的对象大小,因为已经被新的value覆盖了
}
} trimToSize(maxSize); //尝试移除工作
return true;
}
private void trimToSize(int maxSize) {
while (true) {
String key;
Bitmap value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName() + ".sizeOf() is reporting inconsistent results!");
} if (size <= maxSize || map.isEmpty()) { //如果中大小没有超过cacheSize 不需要移除任何对象
break;
} Map.Entry<String, Bitmap> toEvict = map.entrySet().iterator().next(); //取最少使用的Item数据
if (toEvict == null) {
break;
}
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key); //移除最近最少使用的
size -= sizeOf(key, value); //更新内存中的 size 大小
}
}
}
移除所有
trimToSize(-1) 这样就OK了。
以前用2个HashMap来实现过LRU ,就是其中一个HashMap存储使用最近的时间,只要调用get被使用 就更新一下当前时间。移除对象的时候 根据时间排序移除时间最老的 也是OK的,但是没有把内存大小算进去。
Android开源项目 Universal imageloader 源码研究之Lru算法的更多相关文章
- Android开源项目 Universal imageloader 源码研究之项目框架
Universal imageloader 的代码并不复杂 重点是缓存,线程池任务 下面都用UML图进行了绘制 基本使用流程就是 初始化配置,设置Options参数,最后Dispaly提交下载 pub ...
- 谷歌开源项目Chromium的源码获取与项目构建(Win7+vs10/vs13)
转自:http://blog.csdn.net/kuerjinjin/article/details/23563059 从12年那会儿开始获取源码和构建chromium项目都是按照那时候的官方要求用w ...
- Android开源git40个App源码
http://www.itbbu.com/1039.html (JamsMusicPlayer)很棒的音乐播放器(new) (F8)日程安排的软件 (Conversations)基于XMPP的 ...
- Android 开源项目源码解析(第二期)
Android 开源项目源码解析(第二期) 阅读目录 android-Ultra-Pull-To-Refresh 源码解析 DynamicLoadApk 源码解析 NineOldAnimations ...
- 10个经典的Android开源项目(附源码包)
最近在抽空学习Android系统开发,对Android学习也比较感兴趣,刚开始学就试着在网上找几个项目源码研究看下,以下就将找到的Android项目源码列出,希望对正在或准备学习Android系统开发 ...
- 从源码研究如何不重启Springboot项目实现redis配置动态切换
上一篇Websocket的续篇暂时还没有动手写,这篇算是插播吧.今天讲讲不重启项目动态切换redis服务. 背景 多个项目或微服务场景下,各个项目都需要配置redis数据源.但是,每当运维搞事时(修改 ...
- 59.Android开源项目及库 (转)
转载 : https://github.com/Tim9Liu9/TimLiu-Android?hmsr=toutiao.io&utm_medium=toutiao.io&utm_so ...
- GitHub 优秀的 Android 开源项目(转)
今天查找资源时看到的一篇文章,总结了很多实用资源,十分感谢原作者分享. 转自:http://blog.csdn.net/shulianghan/article/details/18046021 主要介 ...
- GitHub 优秀的 Android 开源项目
转自:http://blog.csdn.net/shulianghan/article/details/18046021 主要介绍那些不错个性化的View,包括ListView.ActionBar.M ...
随机推荐
- Xcode 5 解决 The operation couldn’t be completed. (NSURLErrorDomain error -1012.) 问题
使用Xcode6.1 SVN 出现问题 The operation couldn’t be completed. (NSURLErrorDomain error -1012.) 解决方法: 打开终端 ...
- BZOJ 1011 遥远的行星
Description 直线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=Mi*Mj/(j-i) 其中A为很小的常量,故 ...
- java interface
- hdu 5135 Little Zu Chongzhi's Triangles
http://acm.hdu.edu.cn/showproblem.php?pid=5135 题意:给你N个木棍的长度,然后让你组成三角形,问你组成的三角形的和最大是多少? 思路:先求出可以组成的所有 ...
- org.springframework.web.context.ContextLoaderListener
ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在web ...
- J2EE和EJB有什么关系?
其实j2EE就是java的企业版,与javaSE(标准版)有是有区别的,所以运行环境会有差异(简单点可以说,这是两组不同的接口),我们一般所熟悉的tomcat仅仅只实现了j2ee的一小部分规范,它只是 ...
- Unity 通过Animation实现控件位置的转换
Unity版本:4.5.1 NGUI版本:3.6.5 参考链接:http://blog.csdn.net/unity3d_xyz/article/details/23035521,作者:CSDN in ...
- BZOJ 1072 [SCOI2007]排列perm
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1268 Solved: 782[Submit][Sta ...
- CF 85D Sum of Medians (五颗线段树)
http://codeforces.com/problemset/problem/85/D 题意: 给你N(0<N<1e5)次操作,每次操作有3种方式, 1.向集合里加一个数a(0< ...
- 线性代数(矩阵乘法):POJ 2778 DNA Sequence
DNA Sequence Description It's well known that DNA Sequence is a sequence only contains A, C, T and ...