深入探讨 java.lang.ref 包

来源:互联网 发布:机房还原软件 编辑:程序博客网 时间:2024/06/11 08:10

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

1、解释

引用类型取得目标对象方式垃圾回收条件是否可能内存泄漏强引用直接调用不回收可能软引用

视内存情况回收不可能弱引用通过 get() 方法永远回收不可能虚引用无法取得不回收可能

类型是否抛出异常示例代码运行结果StrongReference抛出异常见清单 6Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceSoftReference不抛异常,之前的引用自动清空并返回 null见清单 7nullWeakReference同上见清单 8nullPhantomReference抛出异常见清单 9Exception 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
原创粉丝点击