博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LRUCache原理的简单分析
阅读量:6177 次
发布时间:2019-06-21

本文共 2955 字,大约阅读时间需要 9 分钟。

现在大多数的内存缓存都是用这个LRUCache来进行缓存的,算法主要就是 最近最少使用 

但是其中的原理,有时候没有稍微深入研究的话,还是停留下会用的程度上(会用还不行了 :)(捂脸)

深入源码之前先简单的使用一下,图片缓存大致就是这样使用的

//获取应用程序的最大可用内存int maxMemory = (int) Runtime.getRuntime().maxMemory();int cacheSize = maxMemory / 8;LruCache
lruCache = new LruCache
(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { //这里一定要复写 ,返回的是bitmap的大小 return bitmap.getByteCount(); }};Bitmap bitmap = createBitmap() ;lruCache.put("url1", bitmap);lruCache.put("url2", bitmap);lruCache.put("url3", bitmap);Bitmap bitmap1 = lruCache.get("url1")复制代码

上面就是正常的使用;然后就是查看源码中为什么是会是 最近最少使用的算法

  • new 对象需要做的操作

public LruCache(int maxSize) {    if (maxSize <= 0) {        throw new IllegalArgumentException("maxSize <= 0");    }    //maxSize就是我们必须传入的大小限制,    this.maxSize = maxSize;    //注意这里就是使用LinkedHashMap来进行内存缓存的策略    this.map = new LinkedHashMap
(0, 0.75f, true);}put复制代码
  • put的操作,map的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++;        //这里的safeSizeOf 最后会调用sizeOf方法,如果我们复写这个方法就使用,没有复写就返回 1         size += safeSizeOf(key, value);        //这里调用map的put方法,如果previous存在,将这个替换的previous 减去它的大小;        previous = map.put(key, value);        if (previous != null) {            size -= safeSizeOf(key, previous);        }    }    //如果复写这个方法,就会调用,一般不用关心    if (previous != null) {        entryRemoved(false, key, previous, value);    }    //记住下面的方法,就是删除的操作!!!下面会重点介绍    trimToSize(maxSize);    return previous;}复制代码

  • get操作 , map的get方法

public final V get(K key) {    if (key == null) {        throw new NullPointerException("key == null");    }    V mapValue;    synchronized (this) {        mapValue = map.get(key);        if (mapValue != null) {            hitCount++;            return mapValue;        }        missCount++;    }}复制代码

  • 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 || map.isEmpty()) {                break;            }            //如果size > maxSize 就进行删除操作            //这里就是取出map集合的第一个,进行remove,然后再次调用SizeOf更新size。            Map.Entry
toEvict = map.entrySet().iterator().next(); key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); size -= safeSizeOf(key, value); evictionCount++; } entryRemoved(true, key, value, null); }}复制代码

其实LRUCache源码里看的差不多是对LinkedHashMap的封装!主要还是要去查询LinkedHashMap的源码才能知道为什么trimToSize中的方法里map取迭代器的第一个就是删除最近少使用的那个item了。

  • 对于LinkedHashMap的源码分析,,很是详细的!

转载地址:http://fnzda.baihongyu.com/

你可能感兴趣的文章
scala匿名函数
查看>>
vlan技术【实现】vlan简介和SVI实现不同vlan间通信
查看>>
scrapy爬虫初步尝试
查看>>
陈松松:视频制作不出来,跟这7个思维有九成关系
查看>>
形参和实参有何区别
查看>>
我的友情链接
查看>>
MySQL表结构的导入和导出MySQL表结构的导入和导出
查看>>
JavaSE 学习参考:Map容器遍历
查看>>
salt模块命令
查看>>
基于TBDS的flume异常问题排查过程
查看>>
2017/5 JavaScript基础7--- 数组
查看>>
网络时常断网的解决办法
查看>>
第八次作业及答案
查看>>
linux 日志定时清理脚本
查看>>
java老司机面试题
查看>>
Guice AOP
查看>>
懒汉式单例
查看>>
java递归组装树形结构
查看>>
手把手教你自己写一个模糊搜索的下拉框
查看>>
.Net文档图像处理工具包GdPicture.NET发布v14.0.30,改进PDF/OCR生成速度
查看>>