Java學習筆記10
當程式建立物件、陣列等引用型別實體時,系統都會在堆記憶體中為之分配一塊記憶體區,物件就儲存在這塊記憶體區,
當我們建立的物件不再被引用時,所在的記憶體就變成了垃圾,最後等待垃圾回收機制進行回收,Java的垃圾回收機
制具有以下特徵:
1、垃圾回收機制只負責回收堆記憶體中的物件,不會回收任何物理資源,比如資料庫連線、網路IO等資源。
2、程式無法精確控制垃圾回收的執行,垃圾回收會在合適的時候進行,當物件永久性的失去引用後,系統就會在
合適的時候回收它所佔的記憶體。
3、在垃圾回收機制回收任何物件之前,總會先呼叫它的finalize()方法,該方法讓一個引用變數重新引用該物件,從
而導致垃圾回收機制取消回收。
當一個物件在堆記憶體中執行時,根據它被引用變數所引用的狀態,可以把它所處的狀態分成以下三種:
1、可達狀態:當一個物件建立後,若有一個以上的引用變數引用它,則這個物件在程式中處於可達狀態,程式可
通過引用變數來呼叫該物件的Field和方法。
2、可恢復狀態:如果程式中某個物件不再有任何引用變數引用它,它就進入了可恢復狀態,在這種狀態下,系統
的垃圾回收機制準備回收該物件所佔的記憶體,在回收該物件之前,系統會呼叫所有可恢復狀態物件的finalize()方法
進行資源清理。如果系統在呼叫finalize()方法時重新讓一個引用變數引用該物件,則這個物件會再次變為可達狀
態;否則該物件將進入不可達狀態。
3、不可達狀態:當物件與所有引用變數的關聯都被切斷,且系統已經呼叫所有物件的finalize()方法後依然沒有使該
物件變成可達狀態,那麼這個物件將永久性的失去引用,最後變成不可達狀態,當一個物件處於不可達狀態時,系
統才會真正回收該物件所佔的記憶體。
對大部分物件而言,程式裡會有一個引用變數引用該物件,這時最常見的引用方式,除此之外,java.lang.ref包下提
供了3個類:SoftReference、PhantomReference和WeakReference,它們分別代表了系統對物件的3種引用方
式:軟引用、虛引用和弱引用,Java對物件的引用有如下4中方式:
1、強引用:這是Java程式中最常見的引用方式,程式建立一個物件,並把這個物件賦給一個引用變數,程式通過
該引用變數來操作實際的物件。當一個物件被一個或一個以上的引用變數所引用時,它處於可達狀態,不可能被系
統垃圾回收機制回收。
2、軟引用:軟引用需要通過SoftReference類來實現,當一個物件只有軟引用時,它有可能會被垃圾回收機制回
收,對於只有軟引用的物件而言,當系統記憶體空間足夠時,它不會被系統回收,程式也可使用該物件,當系統記憶體
空間不足時,系統可能回收它。軟引用通常用於對記憶體敏感的程式中。
3、弱引用:弱引用時通過WeakReference類實現,弱引用和軟引用很像,但弱引用的引用級別更低,對於只有弱
引用的物件而言,但系統垃圾回收機制執行時,不管系統記憶體是否足夠,總會回收該物件所佔用的記憶體。當然,並
不是說當一個物件只有弱引用時,它就會立即被回收。
4、虛引用:虛引用時通過PhantomReference類實現,虛引用完全類似於沒有引用。虛引用對物件本身沒有太大影
響,物件甚至感覺不到虛引用的存在。如果一個物件只有一個虛引用時,那麼它和沒有引用的效果大致相同。虛引
用主要用於跟蹤物件被垃圾回收的狀態,虛引用不能單獨使用,虛引用必須和引用佇列(ReferenceQueue)聯合使
用。
引用物件由java.lang.ref.ReferenceQueue類表示,它用於儲存被回收後物件的引用,當聯合使用軟引用、弱引用和
引用佇列時,系統在回收被引用的物件之後,將把被回收物件對應的引用新增到關聯的引用佇列中。與軟引用和弱
引用不同的是,虛引用在物件被釋放之前,將把它物件的虛引用新增到它關聯的引用佇列中,這使得可以在物件被
回收之前採取行動。
軟引用和弱引用可以單獨使用,但虛引用不能單獨使用,單獨使用虛引用沒有太大的意義,虛引用的主要作用就是
跟蹤物件被垃圾回收的狀態,程式可以通過檢查與虛引用關聯的引用佇列中是否已經包含了該虛引用,從而瞭解虛
引用所引用的物件是否即將被回收。