天天看點

深入了解JVM--垃圾收集算法

深入了解JVM--垃圾收集算法

    • 标記-清除算法
    • 複制算法
    • 标記-整理算法
    • 分代收集算法
    • HotSpot的算法實作

标記-清除算法

算法分為"标記"和"清除"兩個階段: 首先标記出所有需要回收的對象,在标記完成後,統一回收所有被标記的對象。

它是最基礎的收集算法,會帶來兩個明顯的問題

  1. 效率問題:标記和清除兩個過程的效率都不高
  2. 空間問題:标記清除之後會産生大量不連續的記憶體碎片,空間碎片太多可能會導緻在程式運作過程中需要配置設定對象時,無法找到足夠的連續的記憶體而不得不提前觸發另一次垃圾收集動作。
    深入了解JVM--垃圾收集算法

複制算法

為了解決效率問題,“複制”收集算法出現了。

它可以将可用記憶體按容量劃分為大小相等的兩快,每次隻使用其中的一塊。當這一塊的記憶體用完了,就将還存活着的對象複制到另一塊上面,然後再把已使用過的記憶體空間一次清空。這樣使得每次都是對整個半區進行記憶體回收,記憶體配置設定時也就不用考慮記憶體碎片等複雜情況,隻要移動堆頂指針,按順序配置設定記憶體即可,實作簡單,運作高效。

  現在的商業虛拟機都采用這種收集算法回收新生代。

  

深入了解JVM--垃圾收集算法

标記-整理算法

根據老年代的特點特出的一種标記算法,标記過程仍然與“标記-清除”算法一樣,但後續步驟不是直接對可回收對象回收,而是讓所有存活的對象向一段移動,然後直接清理掉端邊界以外的記憶體。

深入了解JVM--垃圾收集算法

分代收集算法

目前商業虛拟機的垃圾收集都采用"分代收集"(Denarationl Collection)算法。

這種算法沒有什麼新的思想,隻是根據對象存活周期的不同将記憶體分為幾塊。一般将java堆分為新生代和老年代,這樣我們就可以根據各個年代的特點選擇合适的垃圾收集算法。

比如在新生代中,每次收集都會有大量對象死去,是以可以選擇複制算法,隻需要付出少量對象的複制成本就可以完成每次垃圾收集。而老年代的對象存活幾率是比較高的是以我們可以選擇“标記-清理”或“标記-整理”算法進行垃圾收集。

HotSpot的算法實作

  • 枚舉跟節點

      GC停頓:可達性分析工作必須在一個能確定一緻性的快照中進行。"一緻性"是指在整個執行系統看起來就像被當機在某個時間上,不可以出現分析過程中對象引用關系還在不斷變化的情況,該點不滿足的話分析結果準确性就無法得到保證。這點是導緻GC進行時必須停頓所有Java執行線程的其中一個重要的原因,即使是号稱幾乎不會發生GC停頓的CMS收集起中,枚舉根節點時也是必須停頓的。  

      在HotSpot的實作中,是使用一組稱為OopMap的資料結構來達到這個目的的,在類加載完成的時候,HotSpot就把對象内什麼偏移量上是什麼類型的資料計算出來,在JIT編譯過程中,也會在特定的位置記錄下棧和寄存器中哪些位置是引用。這樣GC在掃描時就可以得知這些資訊類。

  • 安全點

      HotSpot沒有為每條指令都生成OopMap,隻是在"特定位置"記錄類這些資訊,這些位置稱為安全點(Safepoint),即程式執行時并非所有地方都能停頓下來開始GC,隻有到達安全點時才能暫停。

      Safepoint標明既不能太少以至于GC等待時間太長,也不能過于頻繁以至于過分增大運作的負荷。是以安全點的標明基本上是一程式"是否有讓程式長時間執行的特征"為标準標明的,因為每條指令執行的時間都非常短暫,程式不太可能因為指令流長度這個原因而過長時間運作,"長時間執行"的最明顯的特征就是指令序列複用,例如方法調用、循環跳轉、異常跳轉等,是以具有這些功能的指令才會産生Safeponit。

      

    如何在GC發生發生時讓所有線程(不包括執行JNI調用的線程)都在最近的安全點上才停下來。有兩種方案可供選擇:

      1. 搶先式中斷(Preemtive Suspension):不需要線程的執行代碼主動去配合,在GC發生時,首先把所有線程全部中斷,如果發現有線程中斷的地方不再安全點上,就恢複線程讓它跑到安全點上。(現在幾乎沒有虛拟機實作采用搶先式中斷來暫停線程響應GC事件)

      2. 主動式中斷(Boluntary Suspension):思想是當GC需要中斷線程的時候,不直對線程操作,僅僅簡單地設定一個标志,各個線程執行是主動去輪詢這個标志,發現中斷标志為真時就自己中斷挂起。輪詢标志的地方和安全點是重合的。另外再加上建立對象需要配置設定記憶體的地方。

  • 安全區域(Safe Regin)

      安全區域是指在一端代碼片段中,引用關系不會發生變化。在這個區域的任意地方開始GC都是安全的,我們可以把Safe Regin看作是被擴充了的Safepoint。

這裡是引用

https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247483914&idx=1&sn=9aa157d4a1570962c39783cdeec7e539&chksm=fd98546bcaefdd7d9f61cd356e5584e56b64e234c3a403ed93cb6d4dde07a505e3000fd0c427#rd

https://www.cnblogs.com/lrh-xl/p/5292495.html