当前位置: 首页 > Thinking in Java > 正文
第17章 – 深入研究容器 – 持有引用(软引用,弱引用,虚引用)
Mar182015
作者:边城网事 发布:2015-03-18 21:30 分类:Thinking in Java 阅读:1,075 抢沙发
详情见代码注释
package holding; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class TestReference { public static void main(String[] args) { ReferenceQueue rQueue = new ReferenceQueue(); //引用队列 VeryBig softObj = new VeryBig("soft"); //创建一个软引用对象 中 引用的对象,softObj 是强引用,强引用了这个new VeryBig("soft") SoftReference softReference = new SoftReference(softObj,rQueue); //创建软引用对象 //软引用中引用的对象只有在内存不足时才会回收(在抛出OutOfMemory之前). //回收之前,软引用中的对象是软可到达的(即,没有强引用指向new VeryBig("soft"),通过下面的softObj = null;实现) //并且,softObj只有softReference与之关联了,这样softObj就是软可到达的. //软可到达的对象,在系统正常(不存在OutOfMemroy这种情况)时,可以调用softReference.get()方法获取软可到达的对象并且正常使用. //一旦达到软引用的回收条件后(系统快要OutOfMemory了),softReference的get返回null, //此时系统并不是立刻回收软引用中引用的对象,而是,先将该软引用对象本身被放入引用队列中. //(当软引用的get方法返回null之后,这个软引用对象本身 立刻被 放入ReferenceQueue中) //然后系统做了两件事情:(1)调用软引用 中引用对象的finalization过程 (2)真正的回收垃圾. //也就是说,get方法返回null时,软引用中的对象还没有被立即回收. Reference<? extends VeryBig> inq = rQueue.poll(); //检查队列中是否存在立即可用对象,如果存在则将该对象从队列中移除,并立即返回该对象 if(! (null == inq) ) { System.out.println("已经进入ReferenceQueue"); //这里不会执行,因为现在软引用没有放入ReferenceQueue中 } softObj = null; System.gc(); //这里一般不会回收软引用指向的对象,因为系统对内存还充足,不足以抛出OutOfMemory异常 inq = rQueue.poll(); if(! (null == inq) ) { System.out.println("SoftReference 已经进入ReferenceQueue"); //这里也不会执行,因为现在软引用没有放入ReferenceQueue中 } /**********************************分隔符********************************************/ VeryBig weakObj = new VeryBig("weak"); WeakReference weakReference = new WeakReference(weakObj,rQueue); //弱引用对象给软引用类似,但是,只要系统调用垃圾回收,弱可到达的对象立刻被回收. //然后弱引用对象的get方法返回null. //然后,这个软引用对象本身被放入ReferenceQueue中. //(弱可到达的是指,没有强引用指向weakObj(这里通过weakObj = null实现), //weakObj只与weakReference关联) //可以理解为,当调用System.gc()之后,这里的弱可到达的weakObj //即将被回收,此时弱引用对象本身被放入ReferenceQueue中, //然后,系统做了两件事,(1)调用弱引用 中引用对象的finalization过程 (2)真正的回收垃圾. //需要注意的时,调用finalization过程和真正的回收垃圾发生时间不确定,甚至有时候并不发生. inq = rQueue.poll(); if(! (null == inq) ) { System.out.println("weakReference 已经进入ReferenceQueue"); } weakObj = null; System.gc(); inq = rQueue.poll(); if(! (null == inq) ) { System.out.println("weakReference 已经进入ReferenceQueue"); } /**********************************分隔符********************************************/ //而 虚引用PhantomReference 只有当 Java 垃圾回收器对其所指向的对象真正进行回收时, //会将其加入到这个 ReferenceQueue 对象中,这样就可以追综对象的销毁情况(具体是什么时候销毁的) //同时,虚引用的get()方法总是返回null. //虚引用的例子参考:http://jackyin5918.iteye.com/blog/1882292 最后 } } class VeryBig { private static final int SIZE = 10000; private long[] la = new long[SIZE]; private String ident; public VeryBig(String id) { ident = id; } public String toString() { return ident; } protected void finalize() { System.out.println("Finalizing " + ident); } }
赞 赏
微信赞赏
支付宝赞赏
本文固定链接: https://www.jack-yin.com/coding/thinking-in-java/2114.html | 边城网事
【上一篇】第17章 – 深入研究容器 – Collection(List,Set,Queue)的性能测试框架(单线程中)(P501)
【下一篇】第11章 – 持有对象 – 总结,Collection 和 Map
【下一篇】第11章 – 持有对象 – 总结,Collection 和 Map