Java中PhantomReference、WeakReference、SoftReference有什么区别?

时间:2014-07-02 09:35:26   收藏:0   阅读:175
Java中有多种引用类型,按照从强到弱的顺序分别如下:
下面通过代码展现他们之间的不同点。

幽灵引用

为了测试被引用的对象是否存在,只能通过全局的内存使用情况。实验结果是幽灵引用确实能阻止内存被回收,但是finalize在回收的时候才被调用,与文档描述不符。下面请看代码示例:

import java.lang.ref.*;
import java.util.*;


public class Test {
    public static void main(String[] argv) {
        // 查看内存
        // 实验结果是1M
        printMemory();
    
        // 创建一个非常大的对象,便于查看内存使用率,构建一个幽灵引用
        Object phantomObj = new BigObject();
        ReferenceQueue refQ = new ReferenceQueue();
        PhantomReference phantomRef = new PhantomReference(phantomObj, refQ);
        
        // 查看内存
        // 实验结果是101M,说明创建的对象大小是100M
        printMemory();


        // 释放强引用,执行内存回收
        // 期望的输出结果应该是BigObject is finalized,实际结果是Phantom released。说明在只有幽灵引用的情况下finalize没有被调用,与文档描述不符。
        phantomObj = null;
        sleep();
        System.gc();System.gc();System.gc();
        System.out.println("Phantom released");


        // 查看内存
        // 实验结果是101M,说明内存没有被回收
        printMemory();


        // 释放幽灵引用,执行内存回收、
        phantomRef = null;
        refQ = null; // 实验证明:这句话如果没有那么内存不会被释放
        sleep(); // 实验证明:如果没有这句话,输出结果呈现随机性,有时候内存没有回收
        System.gc();System.gc();System.gc();


        // 等内存被回收之后,再查看内存
        // 实验结果是1M,说明内存已经被回收了
        printMemory();
    }
    
    private static void printMemory() {
        System.out.print("The memory usage is: ");
        System.out.println((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024.0/1024.0 + "MB");
    }
    
    private static void sleep() {
        try {
            Thread.sleep(100);
        } catch(InterruptedException ex) {
        }
    }
}


弱引用

下面请看代码示例:

// 构建一个弱引用
String weakObj = new String("Weak Object");
ReferenceQueue weakQueue = new ReferenceQueue();
WeakReference weakReference = new WeakReference(weakObj, weakQueue);
System.out.println("Weak Reference: " + weakReference.get());


// 清空强引用,并执行垃圾回收
weakObj = null;
System.gc();
System.gc();
System.gc();


// 检测弱引用是否可用
// 实验结果:输出结果是null,说明已经被垃圾回收了。
System.out.println("Weak Reference: " + weakReference.get());

软引用

下面请看代码示例:

// 构建一个软引用
String softObj = new String("Soft Object");
ReferenceQueue softQueue = new ReferenceQueue();
SoftReference softRef = new SoftReference(softObj, softQueue);
System.out.println("Soft Reference: " + softRef.get());


// 清空强引用,并执行垃圾回收
softObj = null;
System.gc();
System.gc();
System.gc();


// 检测软引用是否可用
// 输出结果是Soft Object,说明垃圾回收并没有回收软引用。
System.out.println("Soft Reference: " + softRef.get());


// 申请大量内存,直到内存不足
LinkedList li = new LinkedList();
while(true) {
    try {
        li.add(new Object[100000]);
    } catch(OutOfMemoryError e) {
        break;
    }
}
li = null;


// 检测软引用是否可用
// 实验结果:输出null,说明在内存不足之后软引用已经被系统清理了。
System.out.println("Soft Reference: " + softRef.get());


Java中PhantomReference、WeakReference、SoftReference有什么区别?,布布扣,bubuko.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!