WeakReference與SoftReference

WeakReference與SoftReference均可以用來保存對象的實例引用,這兩個類與垃圾回收有關。java

WeakReference是弱引用,其中保存的對象實例能夠被GC回收掉。這個類一般用於在某處保存對象引用,而又不干擾該對象被GC回收,一般用於Debug、內存監視工具等程序中。由於這類程序通常要求即要觀察到對象,又不能影響該對象正常的GC過程。緩存

最近在JDK的Proxy類的實現代碼中也發現了Weakrefrence的應用,Proxy會把動態生成的Class實例暫存於一個由Weakrefrence構成的Map中做爲Cache。工具

SoftReference是強引用,它保存的對象實例,除非JVM即將OutOfMemory,不然不會被GC回收。這個特性使得它特別適合設計對象Cache。對於Cache,咱們但願被緩存的對象最好始終常駐內存,可是若是JVM內存吃緊,爲了避免發生OutOfMemoryError致使系統崩潰,必要的時候也容許JVM回收Cache的內存,待後續合適的時機再把數據從新Load到Cache中。這樣能夠系統設計得更具彈性。測試

WeakReference的一個測試程序設計

import java.lang.ref.WeakReference;code

public class WeakReferenceTest {orm

/**
 * @param args
 */
public static void main(String[] args) {
    A a = new A();
    a.str = "Hello, reference";
    WeakReference<A> weak = new WeakReference<A>(a);
    a = null;
    int i = 0;
    while (weak.get() != null) {
        System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i));
        if (i % 10 == 0) {
            System.gc();
            System.out.println("System.gc() was invoked!");
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {

        }
    }
    System.out.println("object a was cleared by JVM!");
}

} 運行結果: Get str from object of WeakReference: Hello, reference, count: 1對象

Get str from object of WeakReference: Hello, reference, count: 2內存

Get str from object of WeakReference: Hello, reference, count: 3get

Get str from object of WeakReference: Hello, reference, count: 4

Get str from object of WeakReference: Hello, reference, count: 5

Get str from object of WeakReference: Hello, reference, count: 6

Get str from object of WeakReference: Hello, reference, count: 7

Get str from object of WeakReference: Hello, reference, count: 8

Get str from object of WeakReference: Hello, reference, count: 9

Get str from object of WeakReference: Hello, reference, count: 10

System.gc() was invoked!

object a was cleared by JVM!

SoftReference的一個測試程序: import java.lang.ref.SoftReference;

public class SoftReferenceTest {

/**
 * @param args
 */
public static void main(String[] args) {
    A a = new A();
    a.str = "Hello, reference";
    SoftReference<A> sr = new SoftReference<A>(a);
    a = null;
    int i = 0;
    while (sr.get() != null) {
        System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i));
        if (i % 10 == 0) {
            System.gc();
            System.out.println("System.gc() was invoked!");
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {

        }
    }
    System.out.println("object a was cleared by JVM!");
}

}

程序運行結果:

Get str from object of SoftReference: Hello, reference, count: 1

Get str from object of SoftReference: Hello, reference, count: 2

Get str from object of SoftReference: Hello, reference, count: 3

Get str from object of SoftReference: Hello, reference, count: 4

Get str from object of SoftReference: Hello, reference, count: 5

Get str from object of SoftReference: Hello, reference, count: 6

Get str from object of SoftReference: Hello, reference, count: 7

Get str from object of SoftReference: Hello, reference, count: 8

Get str from object of SoftReference: Hello, reference, count: 9

Get str from object of SoftReference: Hello, reference, count: 10

System.gc() was invoked! Get str from object of SoftReference: Hello, reference, count: 11

Get str from object of SoftReference: Hello, reference, count: 12

Get str from object of SoftReference: Hello, reference, count: 13

Get str from object of SoftReference: Hello, reference, count: 14

Get str from object of SoftReference: Hello, reference, count: 15

Get str from object of SoftReference: Hello, reference, count: 16

Get str from object of SoftReference: Hello, reference, count: 17

Get str from object of SoftReference: Hello, reference, count: 18

Get str from object of SoftReference: Hello, reference, count: 19

Get str from object of SoftReference: Hello, reference, count: 20

System.gc() was invoked!

Get str from object of SoftReference: Hello, reference, count: 21

Get str from object of SoftReference: Hello, reference, count: 22

Get str from object of SoftReference: Hello, reference, count: 23

Get str from object of SoftReference: Hello, reference, count: 24

Get str from object of SoftReference: Hello, reference, count: 25

Get str from object of SoftReference: Hello, reference, count: 26

Get str from object of SoftReference: Hello, reference, count: 27

Get str from object of SoftReference: Hello, reference, count: 28

上面的打印結果會一直持續下去。 由於soft.get()一直不會爲空 SoftReference比WeakReference生命力更強,當JVM的內存不吃緊時,即便引用的對象被置爲空了,Soft還能夠保留對該對象的引用,此時的JVM內存池實際上還保有原來對象,只有當內存吃緊的狀況下JVM纔會清除Soft的引用對象,而且會在將來從新加載該引用的對象。

而WeakReference則當清理內存池時會自動清理掉引用的對象。

相關文章
相關標籤/搜索