閱讀983 返回首頁    go 阿裏雲 go 技術社區[雲棲]


G1垃圾收集器介紹

簡介

Oracle在JDK7 update 4之後開始完全支持G1垃圾收集器,G1是一個針對多處理器大容量內存的服務器端的垃圾收集器,其目標是在實現高吞吐量的同時,盡可能的滿足垃圾收集暫停時間的要求。G1在執行一些Java堆空間中的全區域操作(如:全局標記)時是和應用程序線程並發進行的,因此減少了Java堆空間的中斷比例。(譯者注:可簡單理解為減少了Stop-the-World的時間比例)

技術說明

G1收集器通過下麵一些方法實現了高性能和減少暫停時間的目的。

首先將Java堆空間劃分為一些大小相等的區域(region),每個區域都是虛擬機中的一段連續內存空間。G1通過執行並發的全局標記來確定整個Java堆空間中存活的對象。標記階段完成後,G1就知道哪些區域基本上是空閑的。在回收內存時優先回收這些區域,這樣通常都會回收相當數量的內存。這就是為什麼它叫做Garbage-First的原因。顧名思義G1關注某些區域的回收和整理,這些區域中的對象很有可能被完全回收。而且G1使用了一個暫停時間預測模型使得暫停時間控製在用戶指定的暫停時間內,並根據用戶指定的暫停時間來選擇合適的區域回收內存。

G1確定了可回收的區域後就是篩選回收(evacuation)階段了。在此階段將對象從一個或多個區域複製到單一區域,同時整理和釋放內存。該階段是在多個處理器上多個線程並行進行的,因此減少了暫停時間並提高了吞吐量。G1在每一次的垃圾收集過程中都不斷地減少碎片,並能夠將暫停時間控製在一定範圍內。這些已經是以前的垃圾收集器無法完成的了。比如:CMS收集器並不做內存整理。ParallelOld收集器隻是對整個Java堆空間做整理,這樣導致相當長的暫停時間。

關於G1很重要的一點是它並不是一個實時收集器。盡管在絕大多數情況下都能夠滿足暫停時間的要求,但並非沒有例外。因為G1是基於之前數次垃圾收集的經驗值來估計在用戶指定的暫停時間內有多少區域可以收集。因此它對於在區域上執行收集的成本有一個合理的較為精確的模型,並使用該模型來確定對哪些區域執行收集。

對於更詳細的關於使用和配置G1的信息請參考JAVA虛擬機參數

推薦使用的場景

G1的首要目的是為那些需要大容量內存和較小GC延遲的應用程序提供解決方案。這通常是指那些堆大小設置在6GB以上,確定的、可以預測的暫停時間在0.5秒以內的應用程序。

如果應用程序符合以下一項或者多項特征,那麼從CMS或者ParallelOld收集器切換到G1可能更合適。

  • 活動對象占據了超過50%的Java堆空間。
  • 對象分配率或者提升率波動明顯。
  • 不希望有長時間的垃圾收集暫停時間(超過0.5秒或1秒)。

G1的前景

G1的使命是替換掉CMS收集器。通過對比G1和CMS收集器,可以發現G1是更好的一種解決方案。首先G1是一個壓縮收集器,G1通過充分的壓縮完全避免了使用細粒度的空閑列表(free lists)來分配內存,而是使用相對粗粒度的區域(regions)來分配內存。這明顯簡化了收集器,也很大程度上減少了內存碎片化的問題。此外,相比較CMS,G1可以預測出垃圾收集的暫停時間,並允許用戶指定期望的暫停時間。

如果你有興趣改善G1,請通過OpenJDK和郵件列表hotspot-gc-use@openjdk.java.net給我們反饋。

最後更新:2017-05-23 14:01:49

  上一篇:go  《Java特種兵》第一章
  下一篇:go  Java Reflection(二):Classes