WeakReference與SoftReference

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

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

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


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

 

WeakReference的一個測試程序:ide

 

Java代碼  複製代碼   收藏代碼
  1. import java.lang.ref.WeakReference;   
  2.   
  3. public class WeakReferenceTest {   
  4.   
  5.     /**  
  6.      * @param args  
  7.      */  
  8.     public static void main(String[] args) {   
  9.         A a = new A();   
  10.         a.str = "Hello, reference";   
  11.         WeakReference<A> weak = new WeakReference<A>(a);   
  12.         a = null;   
  13.         int i = 0;   
  14.         while (weak.get() != null) {   
  15.             System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i));   
  16.             if (i % 10 == 0) {   
  17.                 System.gc();   
  18.                 System.out.println("System.gc() was invoked!");   
  19.             }   
  20.             try {   
  21.                 Thread.sleep(500);   
  22.             } catch (InterruptedException e) {   
  23.   
  24.             }   
  25.         }   
  26.         System.out.println("object a was cleared by JVM!");   
  27.     }   
  28.   
  29. }  
Java代碼 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://wiseideal.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=import%20java.lang.ref.WeakReference%3B%0A%0Apublic%20class%20WeakReferenceTest%20%7B%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20%40param%20args%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%20%20%20%20%20%20%20%20A%20a%20%3D%20new%20A()%3B%0A%20%20%20%20%20%20%20%20a.str%20%3D%20%22Hello%2C%20reference%22%3B%0A%20%20%20%20%20%20%20%20WeakReference%3CA%3E%20weak%20%3D%20new%20WeakReference%3CA%3E(a)%3B%0A%20%20%20%20%20%20%20%20a%20%3D%20null%3B%0A%20%20%20%20%20%20%20%20int%20i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20while%20(weak.get()%20!%3D%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(String.format(%22Get%20str%20from%20object%20of%20WeakReference%3A%20%25s%2C%20count%3A%20%25d%22%2C%20weak.get().str%2C%20%2B%2Bi))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%25%2010%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.gc()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%22System.gc()%20was%20invoked!%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thread.sleep(500)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(InterruptedException%20e)%20%7B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20System.out.println(%22object%20a%20was%20cleared%20by%20JVM!%22)%3B%0A%20%20%20%20%7D%0A%0A%7D%0A" wmode="transparent">   收藏代碼
  1. import java.lang.ref.WeakReference;  
  2.   
  3. public class WeakReferenceTest {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         A a = new A();  
  10.         a.str = "Hello, reference";  
  11.         WeakReference<A> weak = new WeakReference<A>(a);  
  12.         a = null;  
  13.         int i = 0;  
  14.         while (weak.get() != null) {  
  15.             System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i));  
  16.             if (i % 10 == 0) {  
  17.                 System.gc();  
  18.                 System.out.println("System.gc() was invoked!");  
  19.             }  
  20.             try {  
  21.                 Thread.sleep(500);  
  22.             } catch (InterruptedException e) {  
  23.   
  24.             }  
  25.         }  
  26.         System.out.println("object a was cleared by JVM!");  
  27.     }  
  28.   
  29. }  

 程序運行結果:工具

 

Java代碼  複製代碼   收藏代碼
  1. Get str from object of WeakReference: Hello, reference, count: 1  
  2. Get str from object of WeakReference: Hello, reference, count: 2  
  3. Get str from object of WeakReference: Hello, reference, count: 3  
  4. Get str from object of WeakReference: Hello, reference, count: 4  
  5. Get str from object of WeakReference: Hello, reference, count: 5  
  6. Get str from object of WeakReference: Hello, reference, count: 6  
  7. Get str from object of WeakReference: Hello, reference, count: 7  
  8. Get str from object of WeakReference: Hello, reference, count: 8  
  9. Get str from object of WeakReference: Hello, reference, count: 9  
  10. Get str from object of WeakReference: Hello, reference, count: 10  
  11. System.gc() was invoked!   
  12. object a was cleared by JVM!  
Java代碼 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://wiseideal.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=Get%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%201%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%202%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%203%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%204%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%205%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%206%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%207%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%208%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%209%0AGet%20str%20from%20object%20of%20WeakReference%3A%20Hello%2C%20reference%2C%20count%3A%2010%0ASystem.gc()%20was%20invoked!%0Aobject%20a%20was%20cleared%20by%20JVM!%0A" wmode="transparent">   收藏代碼
  1. Get str from object of WeakReference: Hello, reference, count: 1  
  2. Get str from object of WeakReference: Hello, reference, count: 2  
  3. Get str from object of WeakReference: Hello, reference, count: 3  
  4. Get str from object of WeakReference: Hello, reference, count: 4  
  5. Get str from object of WeakReference: Hello, reference, count: 5  
  6. Get str from object of WeakReference: Hello, reference, count: 6  
  7. Get str from object of WeakReference: Hello, reference, count: 7  
  8. Get str from object of WeakReference: Hello, reference, count: 8  
  9. Get str from object of WeakReference: Hello, reference, count: 9  
  10. Get str from object of WeakReference: Hello, reference, count: 10  
  11. System.gc() was invoked!  
  12. object a was cleared by JVM!  

 

SoftReference的一個測試程序:測試

 

Java代碼  複製代碼   收藏代碼
  1. import java.lang.ref.SoftReference;   
  2.   
  3. public class SoftReferenceTest {   
  4.   
  5.     /**  
  6.      * @param args  
  7.      */  
  8.     public static void main(String[] args) {   
  9.         A a = new A();   
  10.         a.str = "Hello, reference";   
  11.         SoftReference<A> sr = new SoftReference<A>(a);   
  12.         a = null;   
  13.         int i = 0;   
  14.         while (sr.get() != null) {   
  15.             System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i));   
  16.             if (i % 10 == 0) {   
  17.                 System.gc();   
  18.                 System.out.println("System.gc() was invoked!");   
  19.             }   
  20.             try {   
  21.                 Thread.sleep(500);   
  22.             } catch (InterruptedException e) {   
  23.   
  24.             }   
  25.         }   
  26.         System.out.println("object a was cleared by JVM!");   
  27.     }   
  28.   
  29. }  
Java代碼 <EMBED height=15 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=14 src=http://wiseideal.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf allowscriptaccess="always" quality="high" flashvars="clipboard=import%20java.lang.ref.SoftReference%3B%0A%0Apublic%20class%20SoftReferenceTest%20%7B%0A%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20%40param%20args%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%20%20%20%20%20%20%20%20A%20a%20%3D%20new%20A()%3B%0A%20%20%20%20%20%20%20%20a.str%20%3D%20%22Hello%2C%20reference%22%3B%0A%20%20%20%20%20%20%20%20SoftReference%3CA%3E%20sr%20%3D%20new%20SoftReference%3CA%3E(a)%3B%0A%20%20%20%20%20%20%20%20a%20%3D%20null%3B%0A%20%20%20%20%20%20%20%20int%20i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20while%20(sr.get()%20!%3D%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(String.format(%22Get%20str%20from%20object%20of%20SoftReference%3A%20%25s%2C%20count%3A%20%25d%22%2C%20sr.get().str%2C%20%2B%2Bi))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%25%2010%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.gc()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%22System.gc()%20was%20invoked!%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thread.sleep(500)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(InterruptedException%20e)%20%7B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20System.out.println(%22object%20a%20was%20cleared%20by%20JVM!%22)%3B%0A%20%20%20%20%7D%0A%0A%7D" wmode="transparent">   收藏代碼
  1. import java.lang.ref.SoftReference;  
  2.   
  3. public class SoftReferenceTest {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         A a = new A();  
  10.         a.str = "Hello, reference";  
  11.         SoftReference<A> sr = new SoftReference<A>(a);  
  12.         a = null;  
  13.         int i = 0;  
  14.         while (sr.get() != null) {  
  15.             System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i));  
  16.             if (i % 10 == 0) {  
  17.                 System.gc();  
  18.                 System.out.println("System.gc() was invoked!");  
  19.             }  
  20.             try {  
  21.                 Thread.sleep(500);  
  22.             } catch (InterruptedException e) {  
  23.   
  24.             }  
  25.         }  
  26.         System.out.println("object a was cleared by JVM!");  
  27.     }  
  28.   
  29. }  

 程序運行結果:idea

 

Java代碼  複製代碼   收藏代碼
  1. Get str from object of SoftReference: Hello, reference, count: 1  
  2. Get str from object of SoftReference: Hello, reference, count: 2  
  3. Get str from object of SoftReference: Hello, reference, count: 3  
  4. Get str from object of SoftReference: Hello, reference, count: 4  
  5. Get str from object of SoftReference: Hello, reference, count: 5  
  6. Get str from object of SoftReference: Hello, reference, count: 6  
  7. Get str from object of SoftReference: Hello, reference, count: 7  
  8. Get str from object of SoftReference: Hello, reference, count: 8  
  9. Get str from object of SoftReference: Hello, reference, count: 9  
  10. Get str from object of SoftReference: Hello, reference, count: 10  
  11. System.gc() was invoked!   
  12. Get str from object of SoftReference: Hello, reference, count: 11  
  13. Get str from object of SoftReference: Hello, reference, count: 12  
  14. Get str from object of SoftReference: Hello, reference, count: 13  
  15. Get str from object of SoftReference: Hello, reference, count: 14  
  16. Get str from object of SoftReference: Hello, reference, count: 15  
  17. Get str from object of SoftReference: Hello, reference, count: 16  
  18. Get str from object of SoftReference: Hello, reference, count: 17  
  19. Get str from object of SoftReference: Hello, reference, count: 18  
  20. Get str from object of SoftReference: Hello, reference, count: 19  
  21. Get str from object of SoftReference: Hello, reference, count: 20  
  22. System.gc() was invoked!   
  23. Get str from object of SoftReference: Hello, reference, count: 21  
  24. Get str from object of SoftReference: Hello, reference, count: 22  
  25. Get str from object of SoftReference: Hello, reference, count: 23  
  26. Get str from object of SoftReference: Hello, reference, count: 24  
  27. Get str from object of SoftReference: Hello, reference, count: 25  
  28. Get str from object of SoftReference: Hello, reference, count: 26  
  29. Get str from object of SoftReference: Hello, reference, count: 27  
  30. Get str from object of SoftReference: Hello, reference, count: 28  

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