读《java性能权威指南》时,读到了关于强引用,软引用,弱引用,虚引用的介绍。
读完介绍后,又找了一些网上的资料,唯一感到困惑的就是,在什么场景使用?如何使用?
接下来先把从书上读到的,和在网上找到的内容进行一下总结:
1,强引用(Strong references)
例子:
Object strongReference = new Object();
说明:
强引用是我们一般最常的方式。在只要strongReference没有脱离作用域,或没有被设置成null,GC都不会回收它。
回收时机:
(1)脱离作用域:例如,对象被声明在方法内部,方法执行完后。
(2)被设置成null
2,软引用(Soft references)
例子:
Object softReferenceObj = new Object();
SoftReference
说明:
它的使用需要用套在SoftReference
使用被做为软引用的对象时,先要用SoftReference的get方法来看对象是否被回收。如果返回值为null,那对象已经被回收了。
看一些资料上说,软引用非常适合用来做cache,因为它的回收机制是:会尽可能长的保留引用直到 JVM 内存不足时才会被回收。
但“JVM内存不足”是怎么个不足,没有详细说明。《java性能权威指南》详细介绍了一下:
假设堆空间为4G,在Full GC后,堆空间还剩1G,那么如果在过去的1024000(1024x1000)秒内没有访问软引用的话,
GC执行时就会回收它。在没有经过上面的时间之前,即使有GC执行,也不会回收它。
上面的1024是1G的剩余空间变过来的,1000这个值可通过JVM参数(SoftReflRUPolicyMSPerMB)进行调整,
默认值就是1000。上面是对“JVM内存不足”的解释,如果要让GC回收它,必须让这个引用没有强引用,例如:softReferenceObj = null;
但问题是,在什么场景,如何利用这个特性进行设计和运用。因为,这种cache机制建出来的cache,无法控制它,
你不知道何时它就被清理掉了。但它的好处也在于此,不用你自己清理,一般的对象池,需要你自己清理和维护。
如何使用还需要发掘。。。
回收时机:
(1),引用被设置成null
(2),并且,堆的剩余空间*SoftReflRUPolicyMSPerMB值的这么多的时间过去时,还没有被访问。
3,弱引用(Weak references)
例子:
// 也可以用上面的软引用的方式,没有区别
WeakReference weakReference = new WeakReference(new Object());
说明:
弱引用和软引用没有太大的区别,唯一的区别就是不会像软引用那样,在一定时间没有被访问后,才会被回收,而是只要有GC执行,就会回收。
回收时机:
(1),引用被设置成null
(2),有GC执行
4,虚引用(Phantom references)
例子:
ReferenceQueue queue = new ReferenceQueue();
PhantomReference phantomReference= new PhantomReference(new Object(), queue);
说明:
虚引用和弱引用非常相似,但不同的一点是, 用PhantomReference的get方法时,返回值永远为null,也就是说你永远无法通过
PhantomReference来得到它的引用。而且它必须和ReferenceQueue一起使用,当垃圾收集器确定了某个对象是虚可及对象时,
PhantomReference 对象就被放在它的 ReferenceQueue 上。
还有一个不同点是,放入RererenceQueue的时机。当弱引用一旦达到可以被回收的状态时,就会被加入到队列里。但这种状态的对象
可能会因为对象的finalize()
方法里“复活”(或者说回收的更慢)。而PhantomReference对象被放到RererenceQueue的时候,
实际上它已经被从物理内存里清除掉了。它的get方法永远返回null,也防止你”复活“它(或者说妨碍它被释放掉)
问题来了,那我们能用它来做什么呢?看了一些文章,有两个地方可用
1,通过ReferenceQueue,跟踪对象什么时候被释放,或者在它被释放后,做一些后续工作。
2,避免因为finalize()
方法造成很久才能释放。原因如下:实现了finalize()
方法的对象,至少要经过两个GC周期才能被释放。
具体说明参看下面的文章:
http://www.infoq.com/cn/articles/jvm-source-code-analysis-finalreference
https://www.ibm.com/developerworks/cn/java/j-lo-langref/
https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
回收时机:
(1),引用被设置成null
(2),有GC执行
另外还有RererenceQueue,WeakHashMap,这里不多说了,在下面参考的文章写的都挺好的,大家可以自己的看一下。
参考文章:
http://blog.csdn.net/mxbhxx/article/details/9111711(原文:http://www.iteye.com/topic/401478)
http://www.cnblogs.com/skywang12345/p/3154474.html
https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
http://www.infoq.com/cn/articles/jvm-source-code-analysis-finalreference
http://puretech.iteye.com/blog/2008663
http://blog.csdn.net/huoyin/article/details/5891998