1. 程式人生 > >Android面試題——java中引用型別都有哪些

Android面試題——java中引用型別都有哪些

java中引用型別都有哪些

Java中物件的引用分為四種級別,這四種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。

 強引用(StrongReference)

這個就不多說,我們寫程式碼天天在用的就是強引用。如果一個物件被被人擁有強引用,那麼垃圾回收器絕不會回收它。當記憶體空間不足,Java虛擬機器寧願丟擲OutOfMemoryError錯誤,使程式異常終止,也不會靠隨意回收具有強引用的物件來解決記憶體不足問題。

Java的物件是位於heap中的,heap中物件有強可及物件、軟可及物件、弱可及物件、虛可及物件和不可到達物件。應用的強弱順序是強、軟、弱、和虛。對於物件是屬於哪種可及的物件,由他的最強的引用決定。如下程式碼:

String abc=newString("abc");  //1      

      SoftReference<String> softRef=newSoftReference<String>(abc);  //2      

      WeakReference<String> weakRef = newWeakReference<String>(abc); //3      

      abc=null; //4      

      softRef.clear();//5 

第一行在heap堆中建立內容為“abc”的物件,並建立abc到該物件的強引用,該物件是強可及的。

第二行和第三行分別建立對heap中物件的軟引用和弱引用,此時heap中的abc物件已經有3個引用,顯然此時abc物件仍是強可及的。

第四行之後heap中物件不再是強可及的,變成軟可及的。

第五行執行之後變成弱可及的。

 軟引用(SoftReference)

如果一個物件只具有軟引用,那麼如果記憶體空間足夠,垃圾回收器就不會回收它,如果記憶體空間不足了,就會回收這些物件的記憶體。只要垃圾回收器沒有回收它,該物件就可以被程式使用。軟引用可用來實現記憶體敏感的快取記憶體。

軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收,Java虛擬機器就會把這個軟引用加入到與之關聯的引用佇列中。

軟引用是主要用於記憶體敏感的快取記憶體。在jvm報告記憶體不足之前會清除所有的軟引用,這樣以來gc就有可能收集軟可及的物件,可能解決記憶體吃緊問題,避免記憶體溢位。什麼時候會被收集取決於gc的演算法和gc執行時可用記憶體的大小。當gc決定要收集軟引用時執行以下過程,以上面的softRef為例:

    1 首先將softRef的referent(abc)設定為null,不再引用heap中的newString("abc")物件。

    2 將heap中的new String("abc")物件設定為可結束的(finalizable)。

    3 當heap中的new String("abc")物件的finalize()方法被執行而且該物件佔用的記憶體被釋放, softRef被新增到它的ReferenceQueue(如果有的話)中。

   注意:對ReferenceQueue軟引用和弱引用可以有可無,但是虛引用必須有。

  被Soft Reference 指到的物件,即使沒有任何 Direct Reference,也不會被清除。一直要到 JVM 記憶體不足且沒有Direct Reference 時才會清除,SoftReference 是用來設計 object-cache 之用的。如此一來 SoftReference 不但可以把物件 cache 起來,也不會造成記憶體不足的錯誤(OutOfMemoryError)。

 弱引用(WeakReference)

如果一個物件只具有弱引用,那該類就是可有可無的物件,因為只要該物件被gc掃描到了隨時都會把它幹掉。弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒,因此不一定會很快發現那些只具有弱引用的物件。

弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收,Java虛擬機器就會把這個弱引用加入到與之關聯的引用佇列中。

 虛引用(PhantomReference)

"虛引用"顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收。虛引用主要用來跟蹤物件被垃圾回收的活動。

虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列(ReferenceQueue)聯合使用。當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之關聯的引用佇列中。程式可以通過判斷引用佇列中是否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。程式如果發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。

建立虛引用之後通過get方法返回結果始終為null,通過原始碼你會發現,虛引用通向會把引用的物件寫進referent,只是get方法返回結果為null。先看一下和gc互動的過程再說一下他的作用。

  1 不把referent設定為null, 直接把heap中的newString("abc")物件設定為可結束的(finalizable)。

  2 與軟引用和弱引用不同, 先把PhantomRefrence物件新增到它的ReferenceQueue中.然後在釋放虛可及的物件。