OpenJDK 17中的Shenandoah可實現亞毫秒級GC暫停

banq發表於2021-09-18

Redhat在 JDK 12 中釋出了原始的 Shenandoah 垃圾收集器,它實現了併發堆疏散,解決了在不停止應用程式的情況下清理(可能很大)堆的主要問題。這個版本最終被移植到 JDK 11;在 JDK 14 中,實現了併發類解除安裝;在 JDK 16 中,我們新增了併發引用處理,這兩者都進一步減少了垃圾收集操作的暫停時間。暫停下剩餘的垃圾收集操作是執行緒堆疊處理,已經在JDK 17 中解決了這個問題。
下表顯示了 JDK 11、JDK 16 和 JDK 17 中所有基準測試的平均暫停時間。 JDK 16 和 JDK 17 之間的差異顯示了併發堆疊處理所實現的改進。與 JDK 11 的區別是為了完整性而顯示的,包括與以前版本相比的各種其他改進:

JDK 11 1294 微秒
JDK 16  704 微秒
JDK 17  328 微秒
 

OpenJDK 17 中的併發執行緒處理
Java 程式線上程中執行,每個執行緒擁有一個棧:堆疊幀的列表,每個幀儲存著區域性變數、監視器以及與當前執行的方法相關的其他資訊。最重要的是,在 Java 垃圾收集的上下文中,它儲存對堆物件的引用(例如,引用型別化物件的區域性變數)。
透過使用一種稱為堆疊水印的機制(最初由 ZGC 開發人員實現)來實現這一點。中心觀察是所有執行緒堆疊的操作都發生在最頂層的幀中:當前執行的方法。需要做的就是在堆疊幀被銷燬時(例如,透過返回撥用者,或透過丟擲異常)協調 GC 執行緒與正在執行的執行緒,從而退出 GC 處理。這種協調是透過堆疊水印實現的,一個告訴我們堆疊的哪些部分可以安全掃描的指標,以及一個允許垃圾收集器處理返回的屏障。


 

相關文章