深入探讨 java.lang.ref 包

参照:http://www.ibm.com/developerworks/cn/java/j-lo-langref/

1、解释

引用类型 取得目标对象方式 垃圾回收条件 是否可能内存泄漏
强引用 直接调用 不回收 可能
软引用
视内存情况回收 不可能
弱引用 通过 get() 方法 永远回收 不可能
虚引用 无法取得 不回收 可能

  
  

类型 是否抛出异常 示例代码 运行结果
StrongReference 抛出异常 见清单 6 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
SoftReference 不抛异常,之前的引用自动清空并返回 null 见清单 7 null
WeakReference 同上 见清单 8 null
PhantomReference 抛出异常 见清单 9 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
2、代码

package cn.test.ref;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

/**
 * 测试各种引用
 * 让我们来回顾一下四种引用类型的表现以及在垃圾回收器回收清理内存时的表现 .
 * 1、软引用 (SoftReference), 引用类型表现为当内存接近满负荷 , 或对象由 SoftReference.get()
 * 方法的调用没有发生一段时间后 , 垃圾回收器将会清理该对象 . 在运行对象的 finalize 方法前 , 会将软引用对象加入 ReferenceQueue 中去 .
 * 2、弱引用 (WeakReference), 引用类型表现为当系统垃圾回收器开始回收时 , 则立即会回收该对象的引用 .
 * 与软引用一样 , 弱引用也会在运行对象的 finalize 方法之前将弱引用对象加入 ReferenceQueue.
 * 3、强引用 (FinalReference), 这是最常用的引用类型 . JVM 系统采用 Finalizer 来管理每个强引用对象 ,
 * 并将其被标记要清理时加入 ReferenceQueue, 并逐一调用该对象的 finalize() 方法 .
 * 4、虚引用 (PhantomReference), 这是一个最虚幻的引用类型 . 无论是从哪里都无法再次返回被虚引用所引用的对象 .
 * 虚引用在系统垃圾回收器开始回收对象时 , 将直接调用 finalize() 方法 , 但不会立即将其加入回收队列 .
 * 只有在真正对象被 GC 清除时 , 才会将其加入 Reference 队列中去 .
 */
public class TestKindsOfReference {

    /****
     *输出的结果
     ====================begin test softReference==================
     RefTestObj:1没有执行回收
     null
     RefTestObj:1执行回收
     ====================end test softReference====================
     ====================begin test weakReference====================
     RefTestObj:2没有执行回收
     Object [6165421][id=2] come into finalize
     Object [7100506][id=1] come into finalize
     java.lang.ref.WeakReference@11ca803
     null执行回收
     ====================end test weakReference====================
     ====================begin test phantomReference====================
     null没有执行回收
     Object [22266741][id=3] come into finalize
     null
     null
     ====================end test phantomReference====================
     * @param args
     */
    public static void main(String[] args) {
        TestKindsOfReference tst = new TestKindsOfReference();
        tst.testSoftReference();
        tst.testWeakReference();
        tst.testPhantomReference();
    }

    public void testSoftReference(){
        System.out.println("====================begin test softReference==================");
        RefTestObj refTestObj = new RefTestObj();
        refTestObj.setId(1);
        ReferenceQueue<RefTestObj> referenceQueue = new ReferenceQueue<RefTestObj>();
        SoftReference<RefTestObj> softReference = new SoftReference<RefTestObj>(refTestObj,referenceQueue);
        refTestObj = null;
        System.out.println(softReference.get()+"没有执行回收");
        System.gc();
        System.runFinalization();

        System.out.println(referenceQueue.poll());
        System.out.println(softReference.get()+"执行回收");
        System.out.println("====================end test softReference====================");
    }

    public void testWeakReference(){
        System.out.println("====================begin test weakReference====================");
        RefTestObj refTestObj = new RefTestObj();
        refTestObj.setId(2);
        ReferenceQueue<RefTestObj> referenceQueue = new ReferenceQueue<RefTestObj>();
        WeakReference<RefTestObj> weakReference = new WeakReference<RefTestObj>(refTestObj,referenceQueue);
        refTestObj = null;
        System.out.println(weakReference.get()+"没有执行回收");
        System.gc();
        System.runFinalization();

        System.out.println(referenceQueue.poll());
        System.out.println(weakReference.get()+"执行回收");
        System.out.println("====================end test weakReference====================");
    }


    /****
     *1、采用虚引用,无论如何都取不到引用的对象:phantomReference.get()为null
     *2、直接调用 finalize()
     *3、只有在真正对象被 GC 清除时 , 才会将其加入 Reference 队列中去
     */
    public void testPhantomReference(){
        System.out.println("====================begin test phantomReference====================");
        RefTestObj refTestObj = new RefTestObj();
        refTestObj.setId(3);
        ReferenceQueue<RefTestObj> referenceQueue = new ReferenceQueue<RefTestObj>();
        PhantomReference<RefTestObj> phantomReference = new PhantomReference<RefTestObj>(refTestObj,referenceQueue);
        refTestObj = null;
        System.out.println(phantomReference.get()+"没有执行回收");
        System.gc();
        System.runFinalization();  //多次进行垃圾回收,有可能将对象加入到ReferenceQueue中
//        System.gc();
//        System.runFinalization();
//        System.gc();
//        System.runFinalization();
        System.out.println(phantomReference.get());  //不管怎样都都无法取得
        System.out.println(referenceQueue.poll());
        System.out.println("====================end test phantomReference====================");
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值