上篇文章已經介紹了JVM的垃圾回收算法與收集器的實現,垃圾回收算法的基石是引用可達性分析,引用的概念就顯得尤其重要,本文就再談一談引用。java
Java中的引用至關於C++語言中的指針,經過指針/引用能夠定位到另外一塊內存地址中保存的數據,二者的不一樣點在於C++語言中的指針分配的內存須要程序員編碼回收,而Java中的引用則是 「自動」 回收內存。程序員
對於JVM的垃圾回收算法而言,引用的類型決定着被引用的對象的生命週期。算法
引用的類型按引用從強到弱排序包含:強引用(「Strong」 Reference)、軟引用(SoftReference)、弱引用(WeakReference)、虛引用(PhantomReference),對應 Java API 文檔中的 java.lang.ref
包中。緩存
強、弱、軟引用類型之間是能夠直接進行轉換的,這幾種引用不在指向任何對象,而且在 finalize 方法執行後會轉換成虛引用,最後被回收。框架
強引用就是最多見經過 new
關鍵字建立返回的引用,只要強引用指向着對象,那麼垃圾收集器就不會回收此對象。編碼
只有顯示地將引用賦值爲 null
或超過做用域,才能被垃圾回收器收集,回收時機要與具體的回收策略有關。.net
軟引用相較強引用弱一些,當JVM認爲堆內存不足時,垃圾收集器確保在拋出OutOfMemoryError 前,清理軟引用指向的對象。線程
軟引用一般用於實現內存敏感的緩存,當內存足夠時,可保留緩存;當內存不足時,及時清理緩存,以避免耗盡內存。指針
弱引用比軟引用還要弱,提供非強制的映射關係,會被 JVM 擇機清理。code
好比維護一個對象,若是取獲得就使用,取不到就從新實例化。相比軟引用實現的緩存更不容易出現 OutOfMemoryError,經常出如今各大流行框架中做緩存實現。
虛引用又稱幻象引用,是引用類型中最弱的一種,什麼時候被 JVM 回收也不肯定,甚至於經過虛引用沒法獲取引用的對象。
只用於確保在 finalize方法執行後作一些後續操做,如清理等。
對應不一樣引用的強弱,能夠分爲 強可達、軟可達、弱可達、虛可達,除此以外還有不可達 五種可達性級別(reachability level)。
強引用對應的可達性級別,由一個或多個線程經過強引用訪問獲得。一般來講一個線程建立了強引用對象,那麼這個線程對這個對象就是強可達。
軟引用對應的可達性級別,即只能經過軟引用獲取對象時。
弱引用對應的可達性級別,沒法強引用、軟引用訪問,只能經過弱引用訪問的對象,可達性級別爲弱可達。是最接近 finalize 方法執行前的可達性級別。
虛引用(幻象引用)對應的可達性級別,沒有強引用、軟引用、弱引用關聯的對象,通過 finalize 後,只有虛引用引用的對象,可達性級別爲虛引用。
沒有任何引用關聯的對象,可達性級別爲不可達,可直接被垃圾收集器清理。
經過對引用可達性分析,垃圾收集器能夠在合適的時機回收一些不是很緊要的對象,防止內存了溢出的出現。
關於引用類型,總結以下:
同步更新於本人CSDN