gpt4 book ai didi

java - 如何调整G1GC以减小内存占用?

转载 作者:行者123 更新时间:2023-12-02 01:16:50 24 4
gpt4 key购买 nike

我一直在其中一个项目上使用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的人体工程学原理增加了堆大小。



使用并行收集器,可以使用 -XX:GCTimeRatio(吞吐量目标)调整该阈值,但是从 docs中可以看到,没有G1的等效标志。


对于并行收集器,Java SE提供了两个垃圾收集调整参数,这些参数基于实现应用程序的指定行为:最大暂停时间目标和应用程序吞吐量目标;以及请参阅“并行收集器”部分。 (这两个选项在其他收集器中不可用。)请注意,这些行为不能始终得到满足。


我的问题是,除了降低最大堆大小外,如何调整G1GC以减小内存占用量?

在日志中,没有证据表明我超出了最大暂停时间目标,并且确实增加并不能解决问题。



这可能是以下问题的重复: Which JVM Flag sets the GC overhead threshold mentioned in the G1Ergonomics log?,但似乎已接受了错误的答案。 (或者也许仅对于旧版本的JVM是正确的。)

最佳答案

概述:


this Oracle article(1)中,您可以找到G1的最重要标志(包括-XX:MaxGCPauseMillis)。
This bug report表示在G1中也使用了GCTimeRatio标志。
另请参见this related question & answer(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周期。
放宽暂停时间目标,以减少收集时间

关于java - 如何调整G1GC以减小内存占用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57656250/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com