Java長期支持版本Java11發布時推出了ZGC, 之后的Java12 -16均有ZGC的一些更新。然而Java17的新特性已經敲定,確定沒有關于ZGC的相關更新,也從另一方面說明了至Java17 ZGC已經比較穩定,可以作為比較穩定的GC垃圾回收器。相信未來ZGC必定會成為主流的Java垃圾回收期,那么盤一盤ZGC就是必然的了。
1 ZGC從何而來,有什么好處
1.1 ZGC 的命名
根據OpenJDK官方網站的說明ZGC其實并沒有什么特殊意義,就是一個名字而已。起初只是為了致敬ZFS 文件系統,表示ZGC與ZFS一樣都是革命性的,是一個跨時代的產品。更像是一種崇拜命名法。所以ZGC就是要做革命性的與以往的垃圾回收器性能上有很大提高的GC。
1.2ZGC的好處及特點
ZGC是一個低延遲的可擴展GC,它有以下的目標
亞毫秒級別的時間延遲 (就是不超過1毫秒。)
下圖是SPEC做出的測試對比,Java16中ZGC 已經可做到亞毫秒級別的延遲了
2. 暫停時間不會隨著堆的大小、存活集、根集的大小的增加而增加
3. 支持8MB-16TB級別的堆大小
同時ZGC有如下標簽:
- 并發
- 基于Region
- 堆壓縮
- 彩色指針 (對象使用64的指針,有44位表示對象內存地址(如果是8TB , 4TB堆內存則會用到43,42位) ,其中有4位用于GC, 其余為備用 ),個別詳情請看 http://hg.openjdk.java.net/jdk/jdk/rev/24f6b0e413a0
- 負載屏障
- NUMA支持 (每個CPU單獨訪問一塊內存)
2 ZGC如何使用及調優
2.1 ZGC支持那些系統
直至Java17 ZGC基本支持所有的主流系統。
2.2 ZGC可用的調優參數
盡管ZGC有比較大的改動,但是它仍然可以使用絕大部分的GC參數。當然它也有其特有的參數。
2.2.1 ZGC 通用的參數
-XX:MinHeapSize, -Xms 最小堆大小 (default = 8388608 = 8M)
-XX:InitialHeapSize, -Xms 初始化堆大小 (default = 134217728 = 128M )
-XX:MaxHeapSize, -Xmx 最大堆大小 (default = 2134900736 = 2036M)
-XX:SoftMaxHeapSize JVM堆的最大軟限制 (default = 2134900736 = 2036M)
-XX:ConcGCThreads 并發GC的線程數量(default -XX:+ConcGCThreads=1 )
-XX:ParallelGCThreads 設置垃圾回收時的并行GC線程數量 (default = 4 )
-XX:UseLargePages 使用大頁面內存 (dafault false)
-XX:UseTransparentHugePages 使用Transparent大頁面內存
-XX:UseNUMA 使用UNMA內存分配,可以獲得更好的性能
-XX:SoftRefLRUPolicyMSPerMB 每MB的空閑內存空間允許軟引用對象存活時間(default = 1000)
-XX:AllocateHeapAt = 堆分配參數,可以使用非DRAM 內存,這個參數將指向文件系統的文件并使用內存映射來達到在備用存儲設備上進行堆分配。
2.2.2 ZGC 特有的參數
-XX:ZAllocationSpikeTolerance 修正系數,數值越大,越早觸發GC (default = 2.000000)
-XX:ZCollectionInterval ZGC發生的最小時間間隔 ,秒 (default = 0.000000)
-XX:ZFragmentationLimit relocation時,當前region碎片化大于此值,則回收region (default = 25.000000) -XX:ZMarkStackSpaceLimit 指定為標記堆棧分配的最大字節數 (default = 8589934592 = 8096M)
-XX:ZProactive 是否啟用主動回收 (default true)
-XX:ZUncommit 是否歸還不使用的內存給OS(default true)
-XX:ZUncommitDelay 不再使用的內存最多延遲多久會歸還給OS (default = 300 s)
2.2.3 ZGC的一些診斷參數
-XX:+UnlockDiagnosticVMOptions 使用診斷模式,下面的參數才會起作用
-XX:ZStatisticsInterval 指定統計數據輸出之間的時間間隔(秒)。
-XX:ZVerifyForwarding 檢驗轉發表 -XX:ZVerifyMarking 檢驗標記集
-XX:ZVerifyObjects 檢驗對象 -XX:ZVerifyRoots 檢驗根節點
-XX:ZVerifyViews 檢驗堆視圖訪問
2.3 啟用ZGC
-XX:+UseZGC 啟用ZGC
-XX:+UseZGC -Xmx-Xlog:gc
-XX:+UseZGC -Xmx-Xlog:gc* 可以打印更詳細的GC日志
2.4 可優化參數詳解
2.4.1 堆參數的設置
ZGC比較重要的調優參數是設置最大堆內存(-Xmx
)., ZGC設置一個最大堆內存有兩個考量:1.堆可以容納程序的存活集 2.堆中要有足夠的空間允許GC運行時分配.
然而多大內存合適這就要根據 內存使用情況以及GC頻率來確定。
2.4.2 并發GC線程數設置
另一個調優參數就是并發GC線程數量的設置 (-XX:ConcGCThreads=
) 。
一般情況下ZGC可以自動選擇一個合適的值,但是也要根據程序的特點來修改。這個參數對GC使用CPU的時間影響比較大,如果數量太大的話,GC線程會占用過多的CPU時間,數量過少的話垃圾回收有會不及時。通常情況下如果程序的低延遲很重要,那么CPU使用率最好永遠不要超過70%。
2.4.3 將不用的內存返回給OS
默認情況下,ZGC會將不使用的內存還給OS??梢允褂肵X:-ZUncommit 取消這一功能。然而如果實際堆內存比最小堆內存都小的話,肯定不會將不使用的內存返還給OS,另外最大堆內存(-Xmx
)和最小堆內存 (-Xms
) 的設置相等的話,也不會起作用。
另外可以設置延遲歸還對內存的時間 -XX:ZUncommitDelay=
2.4.4 在Linux中開啟大頁支持
在Linux操作系統中,采用內存映射來管理內存,邏輯頁面映射到對應的物理內存,
使用大頁面這個參數在吞吐量,低延遲,啟動時間方面都有很好的性能提升,可以說除了設置起來有點復雜之外,沒有任何的缺點。設置這個參數需要Root權限,所以默認沒有開啟。
2.4.5 Linux中使用大透明頁
Linux下的大頁分為兩種標準,大頁(Huge Pages)和透明大頁(Transparent Huge Pages)。大頁是預分配的方式管理,透明大頁是動態分配的方式。我們可以使用這個參數-XX:+UseTransparentHugePages 來使用 transparent huge pages .對延遲要求很高的程序而言,這個參數是不推薦使用的,它可能會造成不必要的延遲峰值。
2.4.6 配置NUMA的支持
NUMA(非一致性內存訪問)是Intel為了解決SMP多CPU結構中中線訪問方式中資源競爭和一致性問題引起的。ZGC支持NUMA,此特性是默認開啟的,它可以自主判斷系統是否支持NUMA。如果在支持NUMA的機器上運行,那么將有顯著的性能提升。
3 ZGC垃圾回收流程簡述
3.1 ZGC同G1類似,也將內存分為Regions, 叫做ZPages。ZPages可以動態的創建和銷毀,而且還可以動態的變化大小,無論怎么變化均為2MB 的倍數。
ZGC的堆區可以分為Small(2MB) Medium(32MB) Large(N*2MB)等多個Heap Regions. 其中Medium和Large是連續分配的內存。
ZGC的垃圾回收一般可以分為已下幾個步驟流程。
- Pause Mark Start
這個階段會有 STW ,主要對Root集進行掃描,標記Root集中存活對象,即標記根可達對象。 - Concurrent Mark/Remap
并發標記階段,根據上一步標記的根對象去遍歷對象圖,并標記存活對象,主要根據上一步的Root存活對象標記其對象樹上的對象。 - Pause Mark End
標記結束,此處有 STW ,算再標記階段,由于之前標記的時候程序也在運行,此時會有對象引用的變更,此處會對那些變更引用的對象重新標記一下。此時也會清理一些Root對象以及無效空間。 - Concurrent Prepare for Relocate
并發標記Region及處理弱根對象 ,標記需要整理的Region集合,并選擇下一步Relocation要用到的Region集合,也會處理不是強根的對象。 - Pause Relocate Start
開始Relocate,此處有 STW ,處理Root對象的指針,此時會將Roots的對象移動到選好的Region集合中。 - Concurrent Relocate
并發Relocate,此時并發執行,將存活對象移動到上一步選好的新的Region集合中。然后就是清理被釋放的分區,等等工作。
可以看出來ZGC整體使用了標記復制加整理的思想,不過ZGC可以根據當前的內存使用情況,選擇將存活對象整理到一個全新的空Region集合中或者某個存有對象的Region中。由于整個GC的流程中只有三處需要暫停,然而這三處的STW時間都是亞毫秒級別。整個GC的流程延遲總體會小于1ms。
總結
本片總體概括了介紹了比較成熟的ZGC,介紹了ZGC的一些重要調優參數,講解了一下ZGC的垃圾回收流程。相信各位看官也有所收獲。目前ZGC的應用比較少,但隨著Java17的正式推出,那么ZGC必然會逐漸成為主流GC。
-
JAVA
+關注
關注
19文章
2908瀏覽量
103134 -
參數
+關注
關注
11文章
1403瀏覽量
31569 -
文件系統
+關注
關注
0文章
272瀏覽量
19725
發布評論請先 登錄
相關推薦
評論