強引用、軟引用、弱引用、虛引用


原創轉載請注明出處:https://www.cnblogs.com/agilestyle/p/11488192.html

 

從JDK1.2開始,就提供了四種類型的引用:強引用、軟引用、弱引用和虛引用

Java中提供這四種引用類型主要有兩個目的:第一是可以讓程序員通過代碼的方式決定某些對象的生命周期;第二是有利於JVM進行垃圾回收。

 

強引用(StrongReference)

強引用就是指在程序代碼之中普遍存在的,比如下面這段代碼中的object和str都是強引用:

1 Object object = new Object();  
2 String str = "hello";  

只要某個對象有強引用與之關聯,JVM必定不會回收這個對象,即使在內存不足的情況下,JVM寧願拋出OutOfMemory錯誤也不會回收這種對象。

 1 package org.fool.reference;  
 2   
 3 public class StrongReferenceTest {  
 4     public static void main(String[] args) {  
 5         new StrongReferenceTest().test();  
 6     }  
 7   
 8     public void test() {  
 9         /** 
10          * 強引用就是指在程序代碼之中普遍存在的,比如下面這段代碼中的object和objects都是強引用 
11          * 只要某個對象有強引用與之關聯,JVM必定不會回收這個對象,即使在內存不足的情況下, 
12          * JVM寧願拋出OutOfMemory錯誤也不會回收這種對象 
13          */  
14         Object object = new Object();  
15         Object[] objects = new Object[100];  
16         /** 
17          * 當運行至Object[] objArr = new Object[100];這句時,如果內存不足,JVM會拋出OOM錯誤也不會回收object指向的對象。 
18          * 不過要注意的是,當test運行完之后,object和objects都已經不存在了,所以它們指向的對象都會被JVM回收。 
19          * 如果想中斷強引用和某個對象之間的關聯,可以顯示地將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收該對象。 
20          */  
21     }  
22 }  

 

軟引用(SoftReference)

軟引用是用來描述一些有用但並不是必需的對象,在Java中用java.lang.ref.SoftReference類來表示。對於軟引用關聯着的對象,只有在內存不足的時候JVM才會回收該對象

 1 package org.fool.reference;  
 2   
 3 import java.lang.ref.SoftReference;  
 4   
 5 public class SoftRefereneceTest {  
 6     public static void main(String[] args) {  
 7         /** 
 8          * 軟引用是用來描述一些有用但並不是必需的對象,在Java中用java.lang.ref.SoftReference類來表示。 
 9          * 對於軟引用關聯着的對象,只有在內存不足的時候JVM才會回收該對象。因此,這一點可以很好地用來解決OOM的問題, 
10          * 並且這個特性很適合用來實現緩存:比如網頁緩存、圖片緩存等。 
11          * 軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被JVM回收,這個軟引用就會被加入到與之關聯的引用隊列中。 
12          */  
13         SoftReference<String> sr = new SoftReference<>(new String("hello"));  
14           
15         System.out.println(sr.get());   // hello  
16           
17         System.gc();  
18           
19         System.out.println(sr.get());   // hello  
20     }  
21 }

 

弱引用(WeakReference)

弱引用也是用來描述非必需對象的,當JVM進行垃圾回收時,無論內存是否充足,都會回收被弱引用關聯的對象。在java中,用java.lang.ref.WeakReference類來表示。

 1 package org.fool.reference;  
 2   
 3 import java.lang.ref.WeakReference;  
 4   
 5 public class WeakReferenceTest {  
 6     public static void main(String[] args) {  
 7         /** 
 8          * 弱引用也是用來描述非必需對象的,當JVM進行垃圾回收時,無論內存是否充足,都會回收被弱引用關聯的對象。 
 9          * 在java中,用java.lang.ref.WeakReference類來表示。 
10          */  
11         WeakReference<String> wr = new WeakReference<>(new String("hello"));  
12           
13         System.out.println(wr.get());   // hello  
14           
15         System.gc();  
16           
17         System.out.println(wr.get());   // null  
18         /** 
19          * 第二個輸出結果是null,這說明只要JVM進行垃圾回收,被弱引用關聯的對象必定會被回收掉。 
20          * 不過要注意的是,這里所說的被弱引用關聯的對象是指只有弱引用與之關聯, 
21          * 如果存在強引用同時與之關聯,則進行垃圾回收時也不會回收該對象(軟引用也是如此)。 
22          * 弱引用可以和一個引用隊列(ReferenceQueue)聯合使用, 
23          * 如果弱引用所引用的對象被JVM回收,這個軟引用就會被加入到與之關聯的引用隊列中。 
24          */  
25     }  
26 }  

 

虛引用(PhantomReference)

虛引用和前面的軟引用、弱引用不同,它並不影響對象的生命周期。在java中用java.lang.ref.PhantomReference類表示。如果一個對象與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。

 1 package org.fool.reference;  
 2   
 3 import java.lang.ref.PhantomReference;  
 4 import java.lang.ref.ReferenceQueue;  
 5   
 6 public class PhantomReferenceTest {  
 7     public static void main(String[] args) {  
 8         /** 
 9          * 虛引用和前面的軟引用、弱引用不同,它並不影響對象的生命周期。在java中用java.lang.ref.PhantomReference類表示。 
10          * 如果一個對象與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。 
11          * 要注意的是,虛引用必須和引用隊列關聯使用,當垃圾回收器准備回收一個對象時, 
12          * 如果發現它還有虛引用,就會把這個虛引用加入到與之 關聯的引用隊列中。 
13          * 程序可以通過判斷引用隊列中是否已經加入了虛引用,來了解被引用的對象是否將要被垃圾回收。 
14          * 如果程序發現某個虛引用已經被加入到引用隊列,那么就可以在所引用的對象的內存被回收之前采取必要的行動。 
15          */  
16           
17         ReferenceQueue<String> queue = new ReferenceQueue<>();  
18   
19         PhantomReference<String> pr = new PhantomReference<>(new String("hello"), queue);  
20       
21         System.out.println(pr.get());   // null  
22           
23         System.gc();  
24           
25         System.out.println(pr.get());   // null  
26     }  
27 }  

 

對於強引用,我們平時在編寫代碼時經常會用到。而對於其他三種類型的引用,使用得最多的就是軟引用和弱引用,這兩種既有相似之處又有區別。它們都是用來描述非必需對象的,但是被軟引用關聯的對象只有在內存不足時才會被回收,而被弱引用關聯的對象在JVM進行垃圾回收時總會被回收。

 

在SoftReference類中,有三個方法,兩個構造方法(WeakReference類似)和一個get方法:

get方法用來獲取與軟引用關聯的對象的引用,如果該對象被回收了,則返回null。

 

在WeakReference類中,有兩個方法,兩個構造方法

在使用軟引用和弱引用的時候,我們可以顯示地通過System.gc()來通知JVM進行垃圾回收,但是要注意的是,雖然發出了通知,JVM不一定會立刻執行,也就是說這句是無法確保此時JVM一定會進行垃圾回收的。

 

Reference

http://www.cnblogs.com/dolphin0520/p/3784171.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM