簡體   English   中英

如何調整G1GC以減小內存占用?

[英]How can I tune G1GC for smaller memory footprint?

我一直在其中一個項目上使用Java 8(Oracle JVM)進行G1GC實驗。 我的GC標志實際上是:

-Xms64m
-Xmx1024m
-XX:+UseG1GC
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:/tmp/gc.log
-XX:+PrintAdaptiveSizePolicy

我觀察到堆的增長量遠遠大於我擁有的實時數據量。 GC日志顯示了我認為的根本原因:

[G1Ergonomics (Heap Sizing) attempt heap expansion, reason: recent GC overhead higher than threshold after GC, recent GC overhead: 10.17 %, threshold: 10.00 %, uncommitted: 811597824 bytes, calculated expansion amount: 162319564 bytes (20.00 %)]

實際上,我的應用程序會產生大量垃圾,因此GC中花費的時間比例高於10%,因此G1的人體工程學原理增加了堆大小。


使用Parallel收集器,可以使用-XX:GCTimeRatio (吞吐量目標)來調整此閾值,但是從我在文檔中可以看到,G1沒有等效的標志。

對於並行收集器,Java SE提供了兩個垃圾收集調整參數,這些參數基於實現應用程序的指定行為:最大暫停時間目標和應用程序吞吐量目標;以及 請參閱“並行收集器”部分。 (這兩個選項在其他收集器中不可用。)請注意,這些行為不能始終得到滿足。

我的問題是,除了降低最大堆大小之外,如何調整G1GC以減小內存占用量?

在日志中,沒有證據表明我超出了最大暫停時間目標,並且確實增加並不能解決問題。


這可能是這個問題的虛假之處哪個JVM標志設置了G1Ergonomics日志中提到的GC開銷閾值? ,但似乎已接受了錯誤的答案。 (或者也許僅對於舊版本的JVM是正確的。)

概述:

  • 本文 (1)中,您可以找到G1的最重要標志(包括-XX:MaxGCPauseMillis )。

  • 該錯誤報告表明G1中也使用了GCTimeRatio標志。

  • 另請參閱此相關的問題和答案 (2)。

  • 我認為您應該可以通過將-XX:MaxGCPauseMillis設置為更高的值來解決此問題,或者如果您知道您的應用程序創建了很多(年輕)垃圾,則可以使用年輕一代大小的設置。 編輯:好的,對此要非常小心,(1)指出: *年輕代大小*:避免使用-Xmn選項或任何其他相關選項(例如-XX:NewRatio)來顯式設置年輕代大小。 固定年輕一代的大小會覆蓋目標暫停時間目標。


(1)

重要默認值:

G1 GC是具有默認設置的自適應垃圾收集器,可使其無需修改即可高效工作。 這是重要選項及其默認值的列表。 該列表適用於最新的Java HotSpot VM(版本24)。您可以通過在JVM命令行上輸入以下選項並更改設置來適應和調整G1 GC以滿足應用程序的性能需求。

  • -XX:G1HeapRegionSize = n

設置G1區域的大小。 該值為2的冪,范圍為1MB至32MB。 目標是根據最小Java堆大小具有大約2048個區域。

  • -XX:MaxGCPauseMillis = 200

為所需的最大暫停時間設置目標值。 默認值為200毫秒。 指定的值不適合您的堆大小。

  • -XX:G1NewSizePercent = 5

設置要用作年輕代大小的最小值的堆百分比。 默認值為Java堆的5%。 這是一個實驗性標志。 有關示例,請參見“如何解鎖實驗性VM標志”。 此設置替換-XX:DefaultMinNewGenPercent設置。 此設置在Java HotSpot VM(內部版本23)中不可用。

  • -XX:G1MaxNewSizePercent = 60

設置堆大小的百分比,以用作年輕代大小的最大值。 默認值為Java堆的60%。 這是一個實驗性標志。 有關示例,請參見“如何解鎖實驗性VM標志”。 此設置替換-XX:DefaultMaxNewGenPercent設置。 此設置在Java HotSpot VM(內部版本23)中不可用。

  • -XX:ParallelGCThreads = n

設置STW工作線程的值。 將n的值設置為邏輯處理器的數量。 n的值與最多等於8的邏輯處理器的數量相同。

如果邏輯處理器多於八個,則將n的值設置為邏輯處理器的大約5/8。 除較大的SPARC系統外,這在大多數情況下都有效,其中n的值約為邏輯處理器的5/16。

  • -XX:ConcGCThreads = n

設置平行標記線的數量。 將n設置為並行垃圾回收線程數(ParallelGCThreads)的1/4。

  • -XX:InitiatingHeapOccupancyPercent = 45

設置觸發標記周期的Java堆占用閾值。 默認占用率為整個Java堆的45%。

  • -XX:G1MixedGCLiveThresholdPercent = 65

設置要包含在混合垃圾收集周期中的舊區域的占用閾值。 默認占用率為65%。 這是一個實驗性標志。 有關示例,請參見“如何解鎖實驗性VM標志”。 此設置替換-XX:G1OldCSetRegionLiveThresholdPercent設置。 此設置在Java HotSpot VM(內部版本23)中不可用。

  • -XX:G1HeapWastePercent = 10

設置您願意浪費的堆百分比。 當可回收百分比小於堆垃圾百分比時,Java HotSpot VM不會啟動混合垃圾回收周期。 默認值為10%。 此設置在Java HotSpot VM(內部版本23)中不可用。

  • -XX:G1MixedGCCountTarget = 8

設置標記周期后混合垃圾回收的目標數量,以收集具有最多G1MixedGCLIveThresholdPercent個實時數據的舊區域。 默認值為8個混合垃圾回收。 混合館藏的目標是在此目標數量之內。 此設置在Java HotSpot VM(內部版本23)中不可用。

  • -XX:G1OldCSetRegionThresholdPercent = 10

設置在混合垃圾收集周期中要收集的舊區域數的上限。 缺省值為Java堆的10%。 此設置在Java HotSpot VM(內部版本23)中不可用。

  • -XX:G1ReservePercent = 10

設置保留內存的百分比以保持可用,以減少空間溢出的風險。 默認值為10%。 當增加或減少百分比時,請確保將總Java堆調整為相同的數量。 此設置在Java HotSpot VM(內部版本23)中不可用。


(2)

我的猜測是, recent GC overhead higher than threshold正在驅動G1的決策。 您可以通過設置-XX:GCTimeRatio=4來放松它,這將使其相對於GCing的應用程序時間占用20%的CPU周期,而不是10%。

如果太多,您應該

  • 允許它使用更多的CPU內核-可以更輕松地實現其暫停時間目標,這又意味着它可以將收集推遲更長的時間,從而更輕松地實現吞吐量目標。 是的,這確實意味着使用更多的內核實際上可以使用更少的CPU周期。

  • 放寬暫停時間目標,以減少收集時間

經過進一步的調查,似乎G1的人體工程學確實尊重-XX:GCTimeRatio ,盡管文檔說了什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM