Java:对象的强、软、弱、虚引用
转自:
http://zhangjunhd.blog.51cto.com/113473/53092
- ReferenceQueue queue = new ReferenceQueue ();
- PhantomReference pr = new PhantomReference (object, queue);
- MyObject aRef = new MyObject();
- SoftReference aSoftRef=new SoftReference(aRef);
此时,对于这个MyObject对象,有两个引用路径,一个是来自SoftReference对象的软引用,一个来自变量aReference的强引用,所以这个MyObject对象是强可及对象。
- aRef = null;
- MyObject anotherRef=(MyObject)aSoftRef.get();
重新获得对该实例的强引用。而回收之后,调用get()方法就只能得到null了。
- ReferenceQueue queue = new ReferenceQueue();
- SoftReference ref=new SoftReference(aMyObject, queue);
那么当这个SoftReference所软引用的aMyOhject被垃圾收集器回收的同时,ref所强引用的SoftReference对象被列入ReferenceQueue。也就是说,ReferenceQueue中保存的对象是Reference对象,而且是已经失去了它所软引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出,它是一个队列,当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。
- SoftReference ref = null;
- while ((ref = (EmployeeRef) q.poll()) != null) {
- // 清除ref
- }
- 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"
- }
- //setter/getter
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getDepartment() {
- return department;
- }
- public void setDepartment(String department) {
- this.department = department;
- }
- public String getPhone() {
- return Phone;
- }
- public void setPhone(String phone) {
- Phone = phone;
- }
- public int getSalary() {
- return salary;
- }
- public void setSalary(int salary) {
- this.salary = salary;
- }
- public String getOrigin() {
- return origin;
- }
- public void setOrigin(String origin) {
- this.origin = origin;
- }
- }
- 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;// 用于Chche内容的存储
- 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();
- }
- }
无意识对象保留最常见的原因是使用Map将元数据与临时对象(transient object)相关联。假定一个对象具有中等生命周期,比分配它的那个方法调用的生命周期长,但是比应用程序的生命周期短,如客户机的套接字连接。需要将一些元数据与这个套接字关联,如生成连接的用户的标识。在创建Socket时是不知道这些信息的,并且不能将数据添加到Socket对象上,因为不能控制 Socket 类或者它的子类。这时,典型的方法就是在一个全局 Map 中存储这些信息,如下面的 SocketManager 类所示:使用一个全局 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);
- }
- }
- 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();
- }
- }
- 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中的强,软,弱,虚引用
引用的应用场景 我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型.这正是Java中弱引用和软引用的主要区别. 如果一个对象只有弱引用指向 ...
- java中强,软,弱,虚引用 以及WeakHahMap
java中强,软,弱,虚引用 以及WeakHahMap 一:强软引用: 参考:http://zhangjunhd.blog.51cto.com/113473/53092/进行分析 packa ...
- Java:对象的强、软、弱和虚引用
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
- Java对象的强、软、弱和虚引用详解
1.对象的强.软.弱和虚引用 转自:http://zhangjunhd.blog.51cto.com/113473/53092/ 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...
- Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器
//转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...
- Java:对象的强、软、弱和虚引用[转]
原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...
- Java对象的强、软、弱和虚引用+ReferenceQueue
Java对象的强.软.弱和虚引用+ReferenceQueue 一.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足 ...
- Java对象的强、软、弱和虚引用
本文介绍Java对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象 ...
- Java:对象的强、软、弱和虚引用的区别
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
随机推荐
- 使用emIDE创建STM32项目
emIDE是一个开源的嵌入式集成开发环境,基于Code::Blocks开发,能够支持多个平台和多个厂家的嵌入式硬件,继承了Code::Blocks的有点. 下载emIDE并安装,也可选择绿色版.若需要 ...
- oracle 11g安装过程中问题:找不到WFMLRSVCApp.ear
网上的方法是将两个压缩包解压到同一个目录中,我的方法是不再此解压,麻烦,直接将解压出的内容剪切过去,方便省事,原理也是相同的. 解决方法: 将win64_11gR2_database_2of2解压 ...
- JMeter遇到的问题一:Error writing to server(转)
Java.io.IOException: Error writing to server异常:我测试500个并发时,系统没有问题:可当我把线程数加到800时,就出现错误了,在"查看结果树&q ...
- win7 打印机共享
1.在工具->文件夹选项->查看,将"使用简单文件共享"前面的勾勾去掉2.在控制面板->用户帐号,将guest帐户启用3.运行"gpedit.msc&q ...
- 几年前做家教写的C教程(之五专讲结构体与文件操作)
C语言学习宝典(5) 结构体: 将不同类型的数据组合成为一个有机的整体,这个整体就是一个结构体. 例如: Struct student { Int name; Char sex; Float scor ...
- Python安装包或模块的多种方式汇总
windows下安装python第三方包.模块汇总如下(部分方式同样适用于其他平台): 1. windows下最常见的*.exe,*msi文件,直接运行安装即可: 2. 安装easy_install, ...
- AdaBoost算法分析与实现
AdaBoost(自适应boosting,adaptive boosting)算法 算法优缺点: 优点:泛化错误率低,易编码,可用在绝大部分分类器上,无参数调整 缺点:对离群点敏感 适用数据类型:数值 ...
- 移动WEB前端开发资源整合
meta篇 1.视窗宽度 <meta name="viewport" content="width=device-width,initial-scale=1.0,m ...
- 【Android】achartengine的柱状图和饼状图的使用
本文介绍了android中如何使用achartengine绘制饼图和柱状图,请分别尝试饼图和柱状图,曲线图. 先看效果图: 先看看获取数据: Workbook workbook = Workbook. ...
- CodeForces 548
A. Mike and Fax time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...