java弱引用代码 java 弱引用( 三 )


虚引用是java.lang.ref package包中第三种可用的引用,使java.lang.ref.PhantomReference类来表示 。拥有虚引用的对象可以在任何时候被垃圾回收器回收 。和弱引用和软引用相似,你可以通过如下代码创建虚引用:
代码如下:
DigitalCounter digit = new DigitalCounter(); // digit reference variable has strong
reference _ line 3
PhantomReference phantom = new PhantomReference(digit); // phantom reference to object created at line 3
digit = null;
一旦移除强引用 , 第三行的DigitalCounter对象可以在任何时候被垃圾回收器回收 。因为只有一个虚引用指向该对象,而虚引用无法阻止垃圾回收器回收对象 。
除了了解弱引用、软引用、虚引用和WeakHashMap,还需要了解ReferenceQueue 。在创建任何弱引用、软引用和虚引用的过程中你可以通过如下代码提供引用队列ReferenceQueue:
代码如下:
ReferenceQueue refQueue = new ReferenceQueue(); //reference will be stored in this queue for cleanup
DigitalCounter digit = new DigitalCounter();
PhantomReferenceDigitalCounter phantom = new
PhantomReferenceDigitalCounter(digit, refQueue);
引用实例被添加在引用队列中,你可以再任何时候通过查询引用队列回收对象 。一个对象的生命周期可以通过下图进行描述:
在新窗口打开图片
这就是Java中弱引用和软引用的区别 。我们还学到了一些基本的引用类:弱引用、软引用、虚引用以及WeakHashMap和WeakHashMap 。总之,合理的使用引用可以帮助垃圾回收器更好的管理Java内存 。
java三个引用类型四种引用类型
所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱 。
一,强引用
Java中默认声明的就是强引用,比如:
Object obj = new Object(); //只要obj还指向Object对象 , Object对象就不会被回收
obj = null;//手动置null
只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError , 不会去回收 。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来 , JVM就可以适时的回收对象了
二 , 软引用
软引用是用来描述一些非必需但仍有用的对象 。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常 。这种特性常常被用来实现缓存技术,比如网页缓存 , 图片缓存等 。
在 JDK1.2 之后,用java.lang.ref.SoftReference类来表示软引用 。
下面以一个例子来进一步说明强引用和软引用的区别:
在运行下面的Java代码之前,需要先配置参数 -Xms2M -Xmx3M,将 JVM 的初始内存设为2M , 最大可用内存为 3M 。
首先先来测试一下强引用,在限制了 JVM 内存的前提下,下面的代码运行正常
public class TestOOM {
public static void main(String[] args) {
testStrongReference();
}
private static void testStrongReference() {
// 当 new byte为 1M 时,程序运行正常
byte[] buff = new byte[1024 * 1024 * 1];
}
}
但是如果我们将
byte[] buff = new byte[1024 * 1024 * 1];
替换为创建一个大小为 2M 的字节数组
byte[] buff = new byte[1024 * 1024 * 2];
则内存不够使用,程序直接报错,强引用并不会被回收
接着来看一下软引用会有什么不一样 , 在下面的示例中连续创建了 10 个大小为 1M 的字节数组,并赋值给了软引用 , 然后循环遍历将这些对象打印出来 。

推荐阅读