SoftReference(軟引用)、WeakReference(弱引用),這兩個類是對heap中java對象的應用,通過這個兩個類可以和gc做簡單的交互。
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中。這樣可以系統設計得更具彈性。
強引用Object o=new Object(); Object o1=o;
上面代碼中第一句是在heap堆中創建新的Object對象通過o引用這個對象,第二句是通過o建立o1到new Object()這個heap堆中的對象的引用,這兩個引用都是強引用.只要存在對heap中對象的引用,gc就不會收集該對象.如果通過如下代碼:
o=null; o1=null;
如果顯式地設置o和o1為null,或超出范圍,則gc認為該對象不存在引用,這時就可以收集它了。可以收集并不等于就一會被收集,什么時候收集這要取決于gc的算法,這要就帶來很多不確定性。例如你就想指定一個對象,希望下次gc運行時把它收集了,那就沒辦法了,有了其他的兩種引用就可以做到了。其他兩種引用在不妨礙gc收集的情況下,可以做簡單的交互。
heap中對象有強可及對象、軟可及對象、弱可及對象、虛可及對象和不可到達對象。應用的強弱順序是強、軟、弱、和虛。對于對象是屬于哪種可及的對象,由他的最強的引用決定。如下:
WeakReferenceimport java.lang.ref.WeakReference;     public class WeakReferenceTest {         /**       * @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: 3 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!");       }     }總結 SoftReference比WeakReference生命力更強,當JVM的內存不吃緊時,即使引用的對象被置為空了,Soft還可以保留對該對象的引用,此時的JVM內存池實際上還保有原來對象,只有當內存吃緊的情況下JVM才會清除Soft的引用對象,并且會在未來重新加載該引用的對象。而WeakReference則當清理內存池時會自動清理掉引用的對象。
我是天王蓋地虎的分割線參考:http://wiseideal.VEvb.com/blog/1469295
新聞熱點
疑難解答