关于Java的软引用及弱引用
概念介绍
1 Reference
描述一个对象的引用。其内部维持一个queue引用,用于跟踪对象的回收情况,当对象被回收时将当前reference引用入队
2 SoftReference
软引用,仅当JVM内存紧张时会回收关联对象,即JVM在抛出OOM异常之前会回收所有的SoftReference关联的对象。
在对象被回收之后的某个时间点(立即或延迟)进行入队操作
3 WeakReference
弱引用,当JVM执行垃圾回收时(如System.gc触发)回收其关联对象。
在对象被回收之后的某个时间点(立即或延迟)进行入队操作
4 PhantomReference
虚引用,实现了延迟可控、可再生(重复使用对象)的回收机制。
当JVM第一次垃圾回收时并不回收关联对象,而是直接将refercence对象入队;
当reference对象操作出队(poll)时,其内部Queue对象被置换为一个特殊的NULL队列(不允许入队);
于是当JVM第二次垃圾回收时尝试将其入队发现失败,于是JVM才将关联对象回收。
为了保护虚引用对象可再生,该reference的get方法总是返回null。
代码示例
package reference; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class ReferenceTest { public static void main(String[] args) { System.out.println("弱引用=============="); testWeakReference(); System.out.println("软引用=============="); testSoftReference(); System.out.println("虚引用=============="); testPhantomReference(); } /** * 测试弱引用 */ private static void testWeakReference() { Object obj = new Object(); // 构建弱引用 ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>(); WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue); // 关联对象 System.out.println(weakRef.get()); // 检查入队情况 System.out.println(refQueue.poll()); obj = null; System.gc(); // 延迟,等待入队操作执行 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 关联对象是否回收 System.out.println(weakRef.get()); // 是否入队 System.out.println(refQueue.poll()); } /** * 测试软引用 */ private static void testSoftReference() { Object obj = new Object(); ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>(); SoftReference<Object> weakRef = new SoftReference<Object>(obj, refQueue); // 关联对象 System.out.println(weakRef.get()); // 检查入队情况 System.out.println(refQueue.poll()); obj = null; System.gc(); // 延迟,等待入队操作执行 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 关联对象是否回收 System.out.println(weakRef.get()); // 是否入队 System.out.println(refQueue.poll()); } /** * 测试虚引用 */ private static void testPhantomReference() { Object obj = new Object(); ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>(); PhantomReference<Object> weakRef = new PhantomReference<Object>(obj, refQueue); // 关联对象 System.out.println(weakRef.get()); // 检查入队情况 System.out.println(refQueue.poll()); obj = null; System.gc(); // 延迟,等待入队操作执行 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 关联对象是否回收 System.out.println(weakRef.get()); // 是否入队 System.out.println(refQueue.poll()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Phantom Reference's referent recycled."); } }
输出
弱引用============== java.lang.Object@1fb8ee3 null null java.lang.ref.WeakReference@14318bb 软引用============== java.lang.Object@ca0b6 null java.lang.Object@ca0b6 null 虚引用============== null null null java.lang.ref.PhantomReference@1b67f74 Phantom Reference's referent recycled.
相关博文
作者: 美码师(zale)
出处: http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请关注我的公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接 如有问题, 可留言咨询.