1. 程式人生 > >《JDK10新特性官方文件》JEP304: 垃圾收集器介面

《JDK10新特性官方文件》JEP304: 垃圾收集器介面

作者: Roman Kennke

建立時間:2016/08/06 08:45

更新時間:2018/04/09 12:37

型別: 特性

狀態: 已關閉/已提交

元件:hotspot/gc

範圍:實現類

討論: openjdk.java.net上的hotspot-gc-dev

影響:L

持續時間:M

優先順序:4

審閱人:Aleksey Shipilev, Erik Helin, Erik Österlund, Mikael Vidstedt, Per Liden

支持者:Mikael Vidstedt

版本:10

總結

通過引入一套純淨的垃圾收集器介面來將不同垃圾收集器的原始碼分隔開。

提案目的

  • HotSpot內部GC程式碼更好的模組化
  • 在不改變以前程式碼的基礎上使得增加一個新的GC到HotSpot VM更簡單。
  • 從JDK內建的程式碼中刪除GC也更方便了。

非提案目的

  • 不是增加或刪除一個GC
  • 這個工作將進一步改善HotSpot中GC演算法的構建隔離,但並不會完成構建隔離(這屬於另一個提案了)

成功指標

  • 如果GC原始碼的實現包含在各自的src/hotspot/share/gc/$NAME目錄或者src/hotspot/cpu/share/gc/$NAME目錄下就可以認為這次改動成功。這些目錄下的最小化外部程式碼應該包含這些目錄下的內部檔案並且GC特定的if-else分支應該會變得非常少。
  • 這次重構並不會導致效能降低。

動機

現在每個垃圾收集器的實現都是由他們內部src/hotspot/share/gc/$NAME

目錄原始檔組成,例如G1收集器的實現在src/hotspot/share/gc/g1目錄裡,CMS收集器在src/hotspot/share/gc/cms目錄裡等等,然而,有一些零碎的東西分佈在HotSpot的原始碼裡面,比如說,大部分的GC都需要一定的障礙(柵欄),這個實現需要在執行時、直譯器、C1和C2中才能完成,這些屏障(柵欄)不包含在GC指定的目錄下,而是在共享直譯器、C1和C2原始碼中實現(通常巢狀在冗長的if-else鏈中)。同樣的問題也適用於諸如MemoryMXBean之類的診斷程式碼。這種原始碼結構有以下幾個缺點:

  1. 對於GC的開發者來說,實現一個新的垃圾收集器需要了解所有這些地方的知識,以及如何將它們擴充套件到特定的需求。
  2. 對於非GC部分的HotSpot開發者來說,找某個GC特定塊的程式碼是很難的。
  3. 在構建時很難排除指定的垃圾收集器,#define INCLUDE_ALL_GCS一直是構建JVM的一種方式,但只內建了Serial收集器(譯者注:這裡不好翻譯),但是這個機制變得過於僵化。

一個純淨的GC介面將會使實現一個新的垃圾收集器變得更簡單,它將會使這個程式碼結構變得更規範,而且在JVM構建時可以更簡單的排除一個或多個垃圾收集器。當增加一個新的垃圾收集器時,重要的事不是指出程式碼改變部分在HotSpot原始碼中的位置,而是寫好一個好的介面文件說明。

提案描述

這個新的GC介面也會通過CollectedHeap這個類來定義,這個類是每個垃圾收集器需要實現的。這個CollectedHeap類是負責驅動HotSpot的垃圾收集器和剩餘部分的多層面互動(有幾個實用程式類需要在CollectedHeap之前被例項化 )。具體地說,一個垃圾收集器的實現需要提供以下方面的內容:

  • CollectedHeap的子類
  • BarrierSet集合類的子類實現,它實現了在執行時各種各樣的屏障功能。
  • CollectorPolicy類的實現
  • GCInterpreterSupport的實現,它在GC的直譯器功能中提供了各種各樣的柵欄實現(使用匯編指令)。
  • GCC1Support的實現, 它在GC的C1編譯階段是多種屏障(柵欄)功能的實現。
  • GCC2Support的實現, 它在GC的C2編譯階段是多種屏障(柵欄)功能的實現。
  • 最終GC指定引數的初始化
  • 配置一個MemoryService,配置相關的記憶體池沒記憶體管理等等

多個垃圾收集器之間共享的部分程式碼應該存在於一個helper類中,這樣就可以方便的被其他的GC實現類使用,比如說,如果存在一個helper類為牌桌(譯者注:原文card table)實現了多種barrier,然後任何需要牌桌上post-barrier功能的GC只需呼叫helper類中相應的方法即可。這種方法提供了一種靈活的方式實現新barriers,同時允許用混搭的風格去重用已有的程式碼。

替代選擇

一個可替代的選擇是繼續使用現有的結構,這樣做可以使用的更長久,但是會影響未來的新GC演算法的發展和舊GC演算法的移除。

測試

因為這只是一個純粹的程式碼結構型重構,所以以前能正常執行的程式碼重構後也需要能正常執行,並且效能不會有所損失,這裡只需執行基本的迴歸測試就足夠了,不需要新開發新的測試用例。

風險和假設

因為這次就是HotSpot內部程式碼的重構,所以風險會非常低。然而通過引入額外的虛擬呼叫依然可能出現效能下降的風險,可以通過持續性的效能測試去降低這種風險。

依賴性

這個JEP提案將幫助 JEP291: 移除CMS垃圾收集器的實現,應為它提供了一個隔離方案,在需要的情況下允許其它人去維護它。