用Linkedhashmap的LRU特性及SoftReference软引用构建二级缓存

LRU: least recently used(近期最少使用算法)。LinkedHashMap构造函数可以指定其迭代顺序:LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) 设置accessOrder为true,则按照访问顺序迭代。当linkedhashmap调用put或者putall成功插入键值时,会调用removeEldestEntry方法,根据该方法的返回值决定是否删除最老对象(accessOrder为true后根据访问顺序迭代),为了保证map的size不超过某个值,可以重写removeEldestEntry方法,返回true,删除最老对象。

softreference软引用,通过例如new SoftReference<Object>(new Object())这样的方式来保留对一个object的软引用,在即将OOM的时候,GC会将softreference引用的对象回收。所以,在内存充足的时候,它的get()方法返回的是它引用的对象,在因为即将OOM导致GC回收之后,它的get方法返回的是null。

FirstCache.java:

public class FirstCache<K,V> extends LinkedHashMap<K,V>{
    private static final long serialVersionUID = 1L;
    private int MAX_SIZE = 100;
    private SecondCache<K, V> secondCache = new SecondCache<K, V>();
    public FirstCache(){
        super();
    }
    public FirstCache(int max_size){
        //利用linkedHashMap构造方法的accessOrder属性来构建LRU缓存
        //accessOrder为true时,按照访问顺序排序,当accessOrder为false时,按照插入顺序排序
        super(100,0.75f,true);
        this.MAX_SIZE = max_size;
    }
    //当map调用put或者putall方法成功插入一个entry时,根据removeEldestEntry返回的bool值来确定是否删除least recently used对应的数据
    //返回true删除  返回false保留
    @Override
    protected boolean removeEldestEntry(Entry<K,V> entry) {
        if(size() >= MAX_SIZE){
            //用softreference的特点来做二级缓存,softreference(软引用)只有在即将oom的时候 GC才会回收
            secondCache.put(entry.getKey(), entry.getValue());
            System.out.println("二级缓存容量" + secondCache.notEmptySize());
            return true;
        }
        return false;
    }
}

SecondCache.java:

public class SecondCache<K,V> {
    Map<K,SoftReference<V>> secondCacheMap = new HashMap<K, SoftReference<V>>();

    public void put(K k,V v){
        SoftReference<Object> o = new SoftReference<Object>(new Object());
        secondCacheMap.put(k, new SoftReference<V>(v));
    }

    /**
     * 将value为null的键值对删除,返回整个map中value不为null的数量
     */
    public int notEmptySize(){
        int count = 0;
        Iterator<Entry<K, SoftReference<V>>> iter = secondCacheMap.entrySet().iterator();
        while(iter.hasNext()){
            if(iter.next().getValue().get() == null)
                iter.remove();
            else
                count++;
        }
        return count;
    }
}

测试方法:将虚拟机参数设置为-Xms64M -Xmx64M:

public class LRUCache {
    public static final int MAX_SIZE = 20;
    public static int count = 0;
    public static void main(String[] args){
        //一级缓存,利用linkedHashMap的LRU特性
        FirstCache<Integer, Student> firstCache = new FirstCache<Integer, Student>(20);
//        HashMap<Integer, Student> m = new HashMap<Integer, Student>();
        while(true){
            count++;
            Student s = new Student();
            //如果直接使用hashmap来存放,在count大约59的时候就抛出OOM了
//            m.put(count, s);
//            System.out.println(count);
            firstCache.put(count, s);
            if(count > MAX_SIZE){
                System.out.println(firstCache.size());
            }
        }
    }
}
时间: 2024-09-30 06:17:20

用Linkedhashmap的LRU特性及SoftReference软引用构建二级缓存的相关文章

Android开发之图片处理专题(一):利用软引用构建图片高速缓存

在Android开发中,图片处理是一个难点.对于大量的图片处理,一不小心就会出现OOM的错误.那么,构建缓存,就是非常必要的一个手段.利用软引用构建缓存,只是其中步骤之一,我们来看看一般情况下,图篇处理的流程. 一般而言,图片的处理流程大致如上,之前所说的Xutils的原理,也如此.今天,我们就先讲讲如何利用软引用技术来构建高速缓存. 一.对象的四种引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态

Android学习笔记之SoftReference软引用...

PS:其实这一篇和上一篇很类似,都是为了解决内存不足(OOM)这种情况的发生... 学习内容: 1.对象的引用类....   最近也是通过项目中知道了一些东西,涉及到了对象的引用类,对象的引用类分为多种,强引用(其实就是正常的引用),使用SoftReference实现软引用,Weak Reference(弱引用) PhantomRefrence(虚引用)...这三个引用类我只详细的介绍一下SoftReference实现软引用...其他的就一笔带过.... 强引用: Object darker=n

android WeakReference(弱引用 防止内存泄漏)与SoftReference(软引用 实现缓存机制(cache))

在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面将通过两个Demo来结识软引用和弱引用在开发中的运用. 一. WeakReference:防止内存泄漏,要保证内存被虚拟机回收. 下面以一个时间更新的Demo来说明弱引用的运用. 1. main.xml文件代码如下: [html] view plaincopy <?xml version="1

Java 强引用、 软引用、 弱引用、虚引用

 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期.这4种级别由高到低依次为:强引用.软引用.弱引用和虚引用.下图为对象应用类层次. ⑴强引用(StrongReference)   强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内

Java基础 之软引用、弱引用、虚引用

1.概述 在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及状态,程序才能使用它.这 就像在日常生活中,从商店购买了某样物品后,如果有用,就一直保留它,否则就把它扔到垃圾箱,由清洁工人收走.一般说来,如果物品已经被扔到垃圾箱,想再 把它捡回来使用就不可能了.   但有时候情况并不这么简单,你可能会遇到类似鸡肋一样的物品,食之无味,弃之可惜.这种物品现在已经无用了,保留它会占空间,但是立刻扔掉它也不划算,因 为也许将来还会派用场.对于

Java 强引用,软引用,弱引用,虚引用

本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用   在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期.这4种级别由高到低依次为:强引用.软引用.弱引用和虚引用.图1为对象应用类层次. 图1 ⑴强引用(StrongReference)    强引用

Java中的强引用、软引用、弱引用和虚引用

本文为阅读下面四篇博文的读书笔记 http://sishuok.com/forum/blogPost/list/342.html http://blog.sae.sina.com.cn/archives/5228?utm_source=tuicool http://www.cnblogs.com/dolphin0520/p/3784171.html http://blog.csdn.net/arui319/article/details/8489451 四种引用的前世今生 Java 在设计之初就

Java 强引用与软引用以及弱引用,虚引用

1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使 用它.从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期.这4种级别由高到低依次为:强引用.软引用.弱引用和虚引用.图 1为对象应用类层次. 图1 ⑴强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内

java 强引用、软引用、弱引用、虚引用

1.对象的强.软.弱和虚引用    在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期.这4种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 图1为对象应用类层次1)强引用(StrongReference)    强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当