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算法的更多相关文章

  1. Android开源项目 Universal imageloader 源码研究之项目框架

    Universal imageloader 的代码并不复杂 重点是缓存,线程池任务 下面都用UML图进行了绘制 基本使用流程就是 初始化配置,设置Options参数,最后Dispaly提交下载 pub ...

  2. 谷歌开源项目Chromium的源码获取与项目构建(Win7+vs10/vs13)

    转自:http://blog.csdn.net/kuerjinjin/article/details/23563059 从12年那会儿开始获取源码和构建chromium项目都是按照那时候的官方要求用w ...

  3. Android开源git40个App源码

    http://www.itbbu.com/1039.html (JamsMusicPlayer)很棒的音乐播放器(new)   (F8)日程安排的软件   (Conversations)基于XMPP的 ...

  4. Android 开源项目源码解析(第二期)

    Android 开源项目源码解析(第二期) 阅读目录 android-Ultra-Pull-To-Refresh 源码解析 DynamicLoadApk 源码解析 NineOldAnimations ...

  5. 10个经典的Android开源项目(附源码包)

    最近在抽空学习Android系统开发,对Android学习也比较感兴趣,刚开始学就试着在网上找几个项目源码研究看下,以下就将找到的Android项目源码列出,希望对正在或准备学习Android系统开发 ...

  6. 从源码研究如何不重启Springboot项目实现redis配置动态切换

    上一篇Websocket的续篇暂时还没有动手写,这篇算是插播吧.今天讲讲不重启项目动态切换redis服务. 背景 多个项目或微服务场景下,各个项目都需要配置redis数据源.但是,每当运维搞事时(修改 ...

  7. 59.Android开源项目及库 (转)

    转载 : https://github.com/Tim9Liu9/TimLiu-Android?hmsr=toutiao.io&utm_medium=toutiao.io&utm_so ...

  8. GitHub 优秀的 Android 开源项目(转)

    今天查找资源时看到的一篇文章,总结了很多实用资源,十分感谢原作者分享. 转自:http://blog.csdn.net/shulianghan/article/details/18046021 主要介 ...

  9. GitHub 优秀的 Android 开源项目

    转自:http://blog.csdn.net/shulianghan/article/details/18046021 主要介绍那些不错个性化的View,包括ListView.ActionBar.M ...

随机推荐

  1. An Attempt to Understand Boosting Algorithm(s)

    An Attempt to Understand Boosting Algorithm(s) WELCOME! Here you will find daily news and tutorials ...

  2. hdu 5139 Formula

    http://acm.hdu.edu.cn/showproblem.php?pid=5139 思路:这道题要先找规律,f(n)=n!*(n-1)!*(n-2)!.....1!;  不能直接打表,而是离 ...

  3. 工业CF卡与商业CF卡对比

    工业CF卡:1.SLC FLASH芯片 .每个区块读写次数为10万次 2.可分区 识别为本地磁盘 3.平均写入技术.ECC自动校验技术 4.完全模拟硬盘引导系统开机,支持长期稳定工作 商业CF卡:1. ...

  4. 大众点评试水O2O新模式:实体店试穿,扫描二维码付款 现场取货

    在餐饮美食行业取得不错的成绩之后,大众点评将触角延伸到了线下的传统商铺,开始涉足线下商品的 O2O 团购.和传统的线上下单,线下消费的 O2O 模式不同.大众点评的 O2O 团购用户,可在店内试穿后通 ...

  5. delphi XML 原来可以玩接口

    以下代码旨在 脱离TXMLDocument 操作 xml unit Unit3; interface uses Windows, Messages, SysUtils, Variants, Class ...

  6. ♫【HTML5 敏捷实践】第1章 使用语义化的方式实现

    <!DOCTYPE html> 向后兼容的HTML5<doctype>标签.HTML5规范规定<doctype>对大小写不敏感:然而,之前版本的HTML需要< ...

  7. 组合数学(Pólya计数原理):UvaOJ 10601 Cubes

    Cubes You are given 12 rods of equal length. Each of them is colored in certain color. Your task is ...

  8. 图论(2-sat):HDU 4421 Bit Magic

    Bit Magic Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. FFT(快速傅里叶变换):UVAoj 12298 - Super Poker II

    题目:就是现在有一堆扑克里面的牌有无数张, 每种合数的牌有4中不同花色各一张(0, 1都不是合数), 没有质数或者大小是0或者1的牌现在这堆牌中缺失了其中的 c 张牌, 告诉你a, b, c接下来c张 ...

  10. 矩阵(快速幂):COGS 963. [NOI2012] 随机数生成器

    963. [NOI2012] 随机数生成器 ★★   输入文件:randoma.in   输出文件:randoma.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 栋 ...