【问题标题】:InitiatingHeapOccupancyPercent is set to 40 yet old gen memory going beyond 60 percent in G1GCInitiatingHeapOccupancyPercent 设置为 40 但老一代内存在 G1GC 中超过 60%
【发布时间】:2020-04-27 10:21:58
【问题描述】:

我正在尝试解决我的 java 服务中堆内存超过 90% 的问题。

下面是我正在使用的堆配置,

-Xms6144m \
                -Xmx6144m \
                -verbose:gc \
               -XX:G1HeapRegionSize=2097152 \
               -XX:+PrintGC \
               -XX:+PrintFlagsFinal \
               -XX:InitiatingHeapOccupancyPercent=40 \
               -XX:NewRatio=2 \
               -XX:+PrintGCDetails \
               -XX:+PrintGCDateStamps \
               -XX:+PrintAdaptiveSizePolicy \
               -XX:+PrintTenuringDistribution \
               -XX:+UseGCLogFileRotation \
               -XX:NumberOfGCLogFiles=10 \
               -XX:GCLogFileSize=50M \
    -XX:+UnlockExperimentalVMOptions \
  -XX:+UseG1GC -XX:+UseStringDeduplication \
  -XX:+UseCGroupMemoryLimitForHeap \
  -XX:+ParallelRefProcEnabled
  -XX:+OptimizeStringConcat
  -XX:MaxRAMFraction=2 \
  -XshowSettings:vm

问题是我的老一代正在逐渐被填满,随着时间的推移,GC 后堆到达的下限正在增加,我的图表看起来像这样:

您能否建议我的堆参数是否正确,它们的配置方式是否存在冲突,或者如何减少使用的最大堆?

【问题讨论】:

    标签: java memory-management g1gc


    【解决方案1】:

    G1GC 主要是为一件事而设计的,通过以下方式保持您的应用程序响应:

    试图避免“老一代”(应用程序持有一段时间的永久对象,例如来自用户会话、缓存或某种内存泄漏)的垃圾收集必须在单个经典 FullGC,您的应用程序被冻结,而整个堆必须被清理(这取决于对象的数量可能需要很长时间,比如几秒钟。阅读所有关于它的信息 here,其中的一句话:

    目标是回收尽可能多的堆空间(从那些包含最多可回收空间的区域开始)同时尽量不超过暂停时间目标

    您为 InitiatingHeapOccupancyPercent 设置的 40% 与(整个)堆占用率相关,并表示何时开始并发 GC 周期(这应该在日志中可见,如果没有看到:this related question)。根据整个堆的占用情况触发并发 GC 周期的 GC,而不仅仅是其中一个代(因此不仅仅是 Old Gen),包括 G1,使用此选项。值 0 表示“执行恒定的 GC 循环”。默认值为 45。(改编自:Oracle® Communications WebRTC Session Controller System Administrator's Guide

    所以有可能:

    1. GC 循环以 40% 的堆占用率启动,但在完成之前您会达到更高的水平(如 90%),只要您的应用程序正常运行,这可能完全没问题
    2. 您有某种内存泄漏(但如果不知道应用程序及其运行时间或较长时间后的运行情况,则很难从图表中判断出来)
    3. 可能还有一些其他问题,但如果没有要分析的垃圾收集日志就无法判断,但您可能需要参考:Monica Beckwith's article on G1GC 例如Evacuation Failure上的部分

    如果您真的希望您的应用程序使用更少的内存(可能以牺牲一些性能/吞吐量为代价),您可以降低 MaxHeapSize(但您应该使用以下之一:MaxRAMFraction 或 MaxHeapSize (XmX),而不是同时使用两者) .

    或者根据您的应用程序和性能要求考虑使用完全不同的 JVM/垃圾收集器,例如:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多