gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 03:19:09 25 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的人体工程学原理增加了堆大小。

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

For the parallel collector, Java SE provides two garbage collection tuning parameters that are based on achieving a specified behavior of the application: maximum pause time goal and application throughput goal; see the section The Parallel Collector. (These two options are not available in the other collectors.) Note that these behaviors cannot always be met.



我的问题是,除了降低最大堆大小之外,如何调整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表示GCTimeRatio标志也在G1中使用。
  • 另请参阅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/36451454/

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