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());
}
}
} /**
* 占用1M数据
*/
static class Student{
public byte[] datas = new byte[1024*1024];
}
}

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

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

    在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面 ...

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

    PS:其实这一篇和上一篇很类似,都是为了解决内存不足(OOM)这种情况的发生... 学习内容: 1.对象的引用类....   最近也是通过项目中知道了一些东西,涉及到了对象的引用类,对象的引用类分为多 ...

  3. Java系列:使用软引用构建敏感数据的缓存

    一.为什么需要使用软引用    首先,我们看一个雇员信息查询系统的实例.我们将使用一个Java语言实现的雇员信息查询系统查询存储在磁盘文件或者数据库中的雇员人事档案信息.作为一个用户,我们完全有可能需 ...

  4. Android学习笔记之SoftReference软引用,弱引用WeakReference

    SoftReference可以用于bitmap缓存 WeakReference 可以用于handler 非静态内部类和匿名内部类容易造成内存泄漏 private Handler mRemoteHand ...

  5. 软引用SoftReference

    本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有 ...

  6. Java基础 之软引用、弱引用、虚引用 ·[转载]

    Java基础 之软引用.弱引用.虚引用 ·[转载] 2011-11-24 14:43:41 Java基础 之软引用.弱引用.虚引用 浏览(509)|评论(1)   交流分类:Java|笔记分类: Ja ...

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

     1.对象的强.软.弱和虚引用 在JDK 1.2曾经的版本号中.若一个对象不被不论什么变量引用,那么程序就无法再使用这个对象. 也就是说,仅仅有对象处于可触及(reachable)状态.程序才干使 ...

  8. Android 垃圾回收,用软引用建立缓存

    内存对于手机来说是非常重要的. 下面总结了我们在注意创建对象时的规则,以及怎么更好更快的实行GC回收,和怎么构建高速的对象cace缓冲. 1 避免循环遍历的创建对象,哪怕对象很小,也是要占资源的. 2 ...

  9. 转:Java SoftReference 使用构建对象缓存

    本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用   在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说, ...

随机推荐

  1. Ubuntu 14.04 VPS安装配置***的方法

    #安装*** $ sudo apt-get update $ sudo apt-get install python-gevent python-pip $ sudo pip install shad ...

  2. 【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet

    [说明]本系列博文是依据 Emmet 官方文档翻译的,原文地址为:http://docs.emmet.io/,部分内容已经在博主之前的博文中节选过,为方便已经收藏过之前博文的朋友,没有删除这些博文,仅 ...

  3. Shell简介:1分钟理解什么是Shell 脚本语言 解释器 以及编译器和编译语言

    Shell简介:1分钟理解什么是Shell 脚本语言 解释器 以及编译器和编译语言 现在我们使用的操作系统(Windows.Mac OS.Android.iOS 等)都是带图形界面的,简单直观,容易上 ...

  4. JavaScript: window.onload = function() {} 里面的函数不执行

    问题:写了一个最简单的页面.在script标签中使用的 window.onload = function() { function add() { //... } } 页面上:<div oncl ...

  5. (排班表一)使用SQL语句使数据从坚向排列转化成横向排列

    知识重点: 1.extract(day from schedule01::timestamp)=13 Extract 属于 SQL 的 DML(即数据库管理语言)函数,同样,InterBase 也支持 ...

  6. composer环境安装

    PHP很多优秀的框架,例如Laravel等等,镜像都在国外,相关的包管理工具Composer也是在国外,所以安装失败的可能性很大,题主所示的就是因为连不上Composer.解决方法如下: 进入官网, ...

  7. hive连接MySQL报错

    错误如下: [root@awen01 /usr/local/apache-hive-1.2.1-bin]#./bin/hive Logging initialized using configurat ...

  8. 学习python第十四天,模块

    Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码 ...

  9. C# 设置窗口大小为不可调、取消最大化、最小化窗口按键

    this.FormBorderStyle = FormBorderStyle.FixedDialog;//设置边框为不可调节 this.MaximizeBox = false; //取消最大化按键 t ...

  10. 2018Ec-Final比赛总结

    一场匆忙的旅程. NCC_9754_ Victory的最后一场比赛终究没能victory. 去的时候晕车到吐了两次,到宾馆吃完饭直接睡了,但还是两天都昏昏沉沉的头疼的厉害,第二天直接步行去了西工大体育 ...