Java对象的强、软、弱和虚引用详解
1.对象的强、软、弱和虚引用
1.2

ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);
2.对象可及性的判断

3.使用软引用构建敏感数据的缓存
3.1 为什么需要使用软引用
3.2 如果使用软引用
|
MyObject aRef = new MyObject();
SoftReference aSoftRef=new SoftReference(aRef);
|
|
aRef = null;
|
|
MyObject anotherRef=(MyObject)aSoftRef.get();
|
3.3 使用ReferenceQueue清除失去了软引用对象的SoftReference
|
ReferenceQueue queue = new ReferenceQueue();
SoftReference ref=new SoftReference(aMyObject, queue);
|
|
SoftReference ref = null;
while ((ref = (EmployeeRef) q.poll())
!= null) { // 清除ref
}
|
3.4通过软可及对象重获方法实现Java对象的高速缓存
|
public class Employee
{ private String id;// 雇员的标识号码
private String name;// 雇员姓名
private String department;// 该雇员所在部门
private String Phone;// 该雇员联系电话
private int salary;// 该雇员薪资
private String origin;// 该雇员信息的来源
// 构造方法
public Employee(String
id) { this.id =
id; getDataFromlnfoCenter();
}
// 到数据库中取得雇员信息
private void getDataFromlnfoCenter()
{ // 和数据库建立连接井查询该雇员的信息,将查询结果赋值
// 给name,department,plone,salary等变量
// 同时将origin赋值为"From
DataBase" }
……
|
|
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Hashtable;
public class EmployeeCache
{ static private EmployeeCache cache;// 一个Cache实例
private Hashtable<String,EmployeeRef> employeeRefs;// 用于Cache内容的存储
private ReferenceQueue<Employee> q;// 垃圾Reference的队列
// 继承SoftReference,使得每一个实例都具有可识别的标识。
// 并且该标识与其在HashMap内的key相同。
private class EmployeeRef extends SoftReference<Employee>
{ private String _key = "";
public EmployeeRef(Employee
em, ReferenceQueue<Employee> q) { super(em,
q); _key =
em.getID(); }
}
// 构建一个缓存器实例
private EmployeeCache()
{ employeeRefs = new Hashtable<String,EmployeeRef>();
q = new ReferenceQueue<Employee>();
}
// 取得缓存器实例
public static EmployeeCache
getInstance() { if (cache == null)
{ cache = new EmployeeCache();
}
return cache;
}
// 以软引用的方式对一个Employee对象的实例进行引用并保存该引用
private void cacheEmployee(Employee
em) { cleanCache();// 清除垃圾引用
EmployeeRef ref = new EmployeeRef(em, q);
employeeRefs.put(em.getID(),
ref); }
// 依据所指定的ID号,重新获取相应Employee对象的实例
public Employee
getEmployee(String ID) { Employee em = null;
// 缓存中是否有该Employee实例的软引用,如果有,从软引用中取得。
if (employeeRefs.containsKey(ID))
{ EmployeeRef ref = (EmployeeRef) employeeRefs.get(ID);
em = (Employee) ref.get();
}
// 如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,
// 并保存对这个新建实例的软引用
if (em
== null) { em = new Employee(ID);
System.out.println("Retrieve
From EmployeeInfoCenter. ID=" + ID); this.cacheEmployee(em);
}
return em;
}
// 清除那些所软引用的Employee对象已经被回收的EmployeeRef对象
private void cleanCache()
{ EmployeeRef ref = null;
while ((ref
= (EmployeeRef) q.poll()) != null) { employeeRefs.remove(ref._key);
}
}
// 清除Cache内的全部内容
public void clearCache()
{ cleanCache();
employeeRefs.clear();
System.gc();
System.runFinalization();
}
}
|
4.使用弱引用构建非敏感数据的缓存
4.1全局 Map 造成的内存泄漏
Map 将元
|
public class SocketManager
{ private Map<Socket,
User> m = new HashMap<Socket, User>(); public void setUser(Socket
s, User u) { m.put(s,
u); }
public User
getUser(Socket s) { return m.get(s);
}
public void removeUser(Socket
s) { m.remove(s);
}
}
|
4.2如何使用WeakHashMap
|
import java.util.WeakHashMap;
class Element {
private String ident;
public Element(String
id) { ident =
id; }
public String
toString() { return ident;
}
public int hashCode()
{ return ident.hashCode();
}
public boolean equals(Object
obj) { return obj instanceof Element
&& ident.equals(((Element) obj).ident); }
protected void finalize(){
System.out.println("Finalizing
"+getClass().getSimpleName()+" "+ident); }
}
class Key extends Element{
public Key(String
id){ super(id);
}
}
class Value extends Element{
public Value
(String id){ super(id);
}
}
public class CanonicalMapping
{ public static void main(String[]
args){ int size=1000;
Key[] keys=new Key[size];
WeakHashMap<Key,Value> map=new WeakHashMap<Key,Value>();
for(int i=0;i<size;i++){
Key k=new Key(Integer.toString(i));
Value v=new Value(Integer.toString(i));
if(i%3==0)
keys[i]=k;
map.put(k, v);
}
System.gc();
}
}
|
4.3用 WeakHashMap 堵住泄漏
|
public class SocketManager
{ private Map<Socket,User> m = new WeakHashMap<Socket,User>();
public void setUser(Socket
s, User u) { m.put(s,
u); }
public User
getUser(Socket s) { return m.get(s);
}
}
|
4.4配合使用引用队列
Java对象的强、软、弱和虚引用详解的更多相关文章
- java强软弱虚引用详解(转载)
转载自:http://zhangjunhd.blog.51cto.com/113473/53092/ ava:对象的强.软.弱和虚引用 2007-12-01 17:20:20 标签:Java 软引用 ...
- Java 强引用 软引用 弱引用 虚引用详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt393 众所周知,java中是JVM负责内存的分配和回收,这是它的优点(使用方 ...
- java中的强,软,弱,虚引用
引用的应用场景 我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型.这正是Java中弱引用和软引用的主要区别. 如果一个对象只有弱引用指向 ...
- xml和java对象互转:JAXB注解的使用详解
先看工具类: import org.slf4j.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; ...
- Java:对象的强、软、弱、虚引用
转自: http://zhangjunhd.blog.51cto.com/113473/53092 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...
- Java:对象的强、软、弱和虚引用
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
- java基础知识再学习--集合框架-对象的强、软、弱和虚引用
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473/53092 本文 ...
- Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器
//转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...
- Java:对象的强、软、弱和虚引用[转]
原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...
随机推荐
- 如何在django的filter中传递字符串变量作为查询条件(动态改变查询条件)
一般来说在需要查询数据的时候都是以下形式 ret=Articles.objects.filter(id=1) 然而如果要动态的改变查询的条件怎么办呢? 如下代码 def getModelResult( ...
- POJ 3264 Balanced Lineup 简单RMQ
题目:http://poj.org/problem?id=3264 给定一段区间,求其中最大值与最小值的差. #include <stdio.h> #include <algorit ...
- 从IT的角度思考BIM(二):模式与框架
我们满怀着美好期许,鼓起勇气敲响了 BIM 世界的大门.忽然人群中有人高呼:BIM 已死,大家都散了吧! 这时人群开始骚动起来.“我早就说这玩意是忽悠人的吧,你们不信还偏要来”,“我花了好多钱准备这次 ...
- NOI冲刺计划2
吐槽:距离上一次写计划还没有一个月呢,咋又喊要重写捏?可以直接从上一次的计划粘上个一大半. bzoj刷题速度还是在计划之内的,这大半个月中,我bzoj刷进500道,知识方面主要是把莫比乌斯反演系统性的 ...
- hdu 4762 && 2013 ACM/ICPC 长春网络赛解题报告
这次的答案是猜出来的,如果做得话应该是应该是一个几何概型的数学题: 答案就是:n/(m^(n-1)); 具体的证明过程: 1.首先枚举这M个点中的的两个端点,概率是:n*(n-1); 2.假设这个蛋糕 ...
- 【JavaScript】JavaScript函数的参数
要访问js函数中传入的所有参数,可以使用特殊的arguments变量.但是虽然可以像访问数组一样从arguments变量中读取参数,但arguments并非真正的数组.例如,arguments没有pu ...
- 使用jxl.jar操作Excel
在工程的build path中添加jxl.jar,网址:http://www.andykhan.com/jexcelapi/ import java.io.BufferedReader; import ...
- Php使用sqlite
php sqlite文档:http://php.net/manual/en/book.sqlite.php sql:http://www.php100.com/html/webkaifa/PHP/PH ...
- IIS支持net.tcp
绑定 高级设置 http和net.tcp用逗号分隔 //擦擦擦,见鬼了,下面的是tcp.net导致我找了好久,都找不出这个错误 //一定要注意,不要写错了. 否则会收到提示:找不到具有绑定 NetT ...
- POJ_3104_Drying_(二分,最小化最大值)
描述 http://poj.org/problem?id=3104 n件衣服,第i件衣服里面有水a[i],自然风干每分钟干1个水,用吹风机每分钟干k个水,但是同时只能对一件衣服使用吹风机,求干完所有衣 ...