天天看點

JVM-垃圾收集-《深入了解Java虛拟機》學習筆記

垃圾收集

判斷對象已死?

1、引用計數法

給對象添加一個引用計數器。但是很難解決循環引用問題。

2、可達性分析法

通過一系列的 ‘GC Roots’ 的對象作為起始點,從這些節點出發所走過的路徑稱為引用鍊。當一個對象到 GC Roots 沒有任何引用鍊相連的時候說明對象不可用。

可作為GC Roots的對象:

  • 虛拟機棧(棧幀中的本地變量表)中引用的對象
  • 方法區中類靜态屬性引用的對象
  • 方法區中常量引用的對象
  • 本地方法棧中 JNI(即一般說的 Native 方法) 引用的對象
  • 虛拟機中内部的引用
  • 同步鎖持有的對象
  • 反映Java虛拟機内部情況的IMXBean等

再談引用

四種強度的引用類型(由強到弱):

  • 強引用
類似于

Object obj = new Object();

建立的,隻要強引用在就不回收。
  • 軟引用
SoftReference 類實作軟引用。在系統要發生記憶體溢出異常之前,将會把這些對象列進回收範圍之中進行二次回收
  • 弱引用
WeakReference 類實作弱引用。對象隻能生存到下一次垃圾收集之前。在垃圾收集器工作時,無論記憶體是否足夠都會回收掉隻被弱引用關聯的對象
  • 虛引用
PhantomReference 類實作虛引用。無法通過虛引用擷取一個對象的執行個體,為一個對象設定虛引用關聯的唯一目的就是能在這個對象被收集器回收時收到一個系統通知。

生存或死亡

即使在可達性分析算法中不可達的對象,也并非是“facebook”的,這時候它們暫時出于“緩刑”階段,一個對象的真正死亡至少要經曆兩次标記過程:如果對象在進行中可達性分析後發現沒有與 GC Roots 相連接配接的引用鍊,那他将會被第一次标記并且進行一次篩選,篩選條件是此對象是否有必要執行 finalize() 方法。當對象沒有覆寫 finalize() 方法,或者 finalize() 方法已經被虛拟機調用過,虛拟機将這兩種情況都視為“沒有必要執行”。

如果這個對象被判定為有必要執行 finalize() 方法,那麼這個對象竟會放置在一個叫做 F-Queue 的隊列中,并在稍後由一個由虛拟機自動建立的、低優先級的 Finalizer 線程去執行它。這裡所謂的“執行”是指虛拟機會出發這個方法,并不承諾或等待他運作結束。finalize() 方法是對象逃脫死亡命運的最後一次機會,稍後 GC 将對 F-Queue 中的對象進行第二次小規模的标記,如果對象要在 finalize() 中成功拯救自己 —— 隻要重新與引用鍊上的任何一個對象履歷關聯即可。

finalize() 方法隻會被系統自動調用一次。

垃圾回收算法

分代收集理論上:

​ (1) 弱分代假說:絕大多數對象都是朝生夕滅的。

​ (2) 強分代 假說:熬過越多次垃圾收集過程的對象就越 難以消亡。

​ (3) 跨代引用假說:跨代引用相對于同代引用來說僅占 極少數。

​ 跨代解決:在新生代中建立全局資料結構,記憶集,來标記老年代中某塊存在跨代引用

  • 标記清除算法:标記出所有需要回收的對象,最後将這些标記的對象清除掉。優點:簡單。缺點:效率低,産生大量的記憶體碎片
  • 标記整理算法:标記出所有需要回收的對象,把存活的移到一端,然後會清理掉存活區以外的記憶體。優點:得到規整的記憶體。缺點:移動對象比較消耗時間
  • 複制算法:将記憶體回收分為大小相等的兩個部分,在其中一部分進行存儲,當存儲滿了或者空間不夠時,就将空間進行一次垃圾回收,将存活下來的對象放到另一個記憶體上,把用過的那一部厘清楚掉。優點:解決了記憶體碎片問題。缺點:由于很多對象都是朝生夕死的,是以會浪費50%的空間代價。
    • Eden和2個survivor區 8:1
  • 分代回收算法:根據對象的存活周期将對象劃分為新生代和老年代,新生代主要采用複制算法,老年代主要選擇标記整理或者标記清除算法。

HotSpot的算法實作細節(簡單了解)

  • 根節點枚舉
    • 解決方案-OopMap

      一旦類加載動作完成的時候,HotSpot就會把對象内什麼偏移量上是什麼類型的資料計算出來,在即時編譯(見第11章)過程中,也 會在特定的位置記錄下棧裡和寄存器裡哪些位置是引用。這樣收集器在掃描時就可以直接得知這些信 息了,并不需要真正一個不漏地從方法區等GC Roots開始查找。

  • 安全點
    • 隻是在“特定的位置”記錄OopMap,這就是安全點
  • 安全區域
    • 在這個區域内的線程隻能等待周遊OopMap結束才能出來 ,同時,周遊OopMap不需要考慮在安全區域的線程
  • 記憶集與卡表
    • 用來解決跨表引用
    • 表中元素位老年代的記憶體位址
  • 寫屏障
  • 并發的可達性分析
    • 三色标記
      • 原始快照
        • G1 Shenandoah收集器
      • 增量更新
        • CMS收集器