關於Java引用,你必須知道這些

引用

Java 虛擬機接管了全部的內存分配與回收工做,極大地減小了程序員的工做量和錯誤率。GC 在回收內存時,一般採用被稱爲可達性分析的算法判斷一個對象是否能夠回收。而在可達性分析中,對象的引用有着決定性的做用。在下圖中,GC 從 GC Roots 開始順着引用鏈往下尋找對象,發現當前有引用的對象爲object 一、object 二、object 三、object 4,而object 五、object 六、object 7雖然互相之間有引用但已經沒法從外部引用到。所以,圖中 object 1-4 爲存活的對象,而 object 5-7 爲可回收的對象。程序員

 

雖然 GC 可以完成垃圾收集工做,可是仍然沒法避免 out of memory 。一方面在開發過程當中須要注意再也不使用的引用設爲 null 來釋放引用的對象,另外一方面也須要從對象引用的角度考慮使用合適的引用類型更好地管理對象內存。算法

 

 

引用的類型

Java 有4種類型的引用:strong(強引用),soft(軟引用),weak(弱引用)和 phantom(虛引用)。緩存

 

強引用:強引用是在 Java 中的普通引用。任什麼時候候咱們建立一個新的對象,默認狀況下建立一個強引用。例如類的靜態變量,從類被初始化以後便已經分配內存,做爲強引用對象不能被 GC 回收,須要等待虛擬機退出或類被卸載才能釋放引用被 GC 回收。post

 

弱引用:弱引用沒法保證對象必定存活於內存中,被弱引用關聯的對象只能生存到下一次垃圾收集發生以前。咱們可使用 WeakReference 類來實現弱引用。性能

 

 

軟引用:軟引用比弱引用稍強一點,垃圾收集發生時弱引用必定會被回收,而軟引用會請求 GC 保留本身除非沒有其餘選擇,能夠理解爲只在將要發生內存溢出時 GC 纔會回收軟引用。咱們可使用 SoftReference 類來實現軟引用。對象

 

 

虛引用:一個對象是否有虛引用的存在,徹底不會對其生存時間構成影響,也沒法經過虛引用來取得一個對象實例。爲一個對象設置虛引用關聯的惟一目的就是能在這個對象被 GC 回收時收到一個系統通知。咱們可使用 PhantomReference 類來實現虛引用。當 GC 準備回收一個對象時,若是發現它還有虛引用,就會在回收對象的內存以前,把這個虛引用加入到與之關聯的引用隊列中。開發者能夠經過判斷引用隊列中是否包含對象來判斷對象是否即將被回收,能夠在回收以前作些處理。隊列

 

 

引用隊列:若是引用關聯了引用隊列,則 GC 回收對象內存的時候會把引用加入到引用隊列中。當引用隊列中包含引用時,意味着引用指向的堆內存中的對象被回收。內存

 

 

引用的應用

構建緩存資源

使用軟引用能夠用於建立 Java 本地高速緩存,只要內存仍然夠用緩存就不會被刪除,而一旦內存緊張即將溢出時,GC 會刪除部分緩存釋放內存。例如,建立比較耗時影響性能的數據對象、一段時間內能夠重複使用的資源、不常變化的數據等,均可以使用軟引用構建緩存,既能保證讀取性能,又不會致使內存溢出。開發

 

WeakHashMap

WeakHashMap 是以弱引用鍵實現的哈希表。當 WeakHashMap 中的鍵再也不被強引用使用時,GC 下次回收垃圾時將回收此鍵。WeakHashMap 中的鍵被回收後,哈希表的條目也會被 GC 回收。所以,WeakHashMap 能夠用於臨時存儲一些不須要長時間使用的對象,能夠有效避免內存溢出。

 

 

總結

Java 開發中最經常使用的引用是強引用,經過new建立對象獲得強引用。強引用會阻止 GC 釋放對象內存,長時間運行容易致使內存溢出。在開發中,對於強引用變量在使用完畢後應把值設置爲 null 來幫助 GC 進行垃圾回收。在 Java 中還有另外三種引用類型,弱引用、軟引用和虛引用。弱引用和軟引用能夠用於構建緩存和避免內存泄露,虛引用能夠用於獲知對象將被回收的通知並進行處理。

 

四種引用類型的對好比下:

 

原文地址:關於Java引用,你必須知道這些

相關文章
相關標籤/搜索