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則當清理內存池時會自動清理掉引用的對象。