【问题标题】:Max heap size is ignored above 12GB12GB 以上的最大堆大小被忽略
【发布时间】:2017-04-03 19:41:43
【问题描述】:

环境:

  • AWS R4.XLarge(4vCPU,30GB RAM)
  • Windows 2012R2
  • Tomcat 7,jdk-8u102

首先,我不是开发人员,所以请耐心等待。最大堆设置为 24GB 或 16GB 时,Tomcat 仅使用 4GB,一些应用程序抛出 java.lang.OutOfMemoryError: GC 开销限制超出。我的预感是 GC 正在“阻止”Java 访问更多内存。开发者为 GC 启用的默认设置是:

call :set_XX_java_opts "+UseConcMarkSweepGC"

我研究了一下,觉得添加这些参数可以解决这个问题:

call :set_XX_java_opts "+CMSParallelRemarkEnabled"

call :set_XX_java_opts "+ScavengeBeforeFullGC"

call :set_XX_java_opts "+CMSScavengeBeforeRemark"

我走对了吗?

谢谢,

弗雷德

【问题讨论】:

  • 你能分享所有的JVM参数吗?
  • 安装 64 位 Java 而不是 32 位。
  • 如果 tomcat 只使用 4 GB,为什么有些应用程序会抛出 otofmemory ?获取堆转储并分析堆中发生了什么,并确定那里发生了什么。一个不错的链接,您可能想参考plumbr.eu/outofmemoryerror/gc-overhead-limit-exceeded

标签: java tomcat garbage-collection


【解决方案1】:

正如您之前所说,如果超过 98% 的总时间用于垃圾收集并且回收的堆少于 2%,则并行 GC 将抛出 "OutOfMemoryError"

现在,我们发现问题在于 GC 运行过多。 这个问题可以归结为多个桶:

  1. 您创建的对象数量是否比 GC 能够恢复的快得多?
  2. 您的用例是否使用了 corrct GC 算法?
  3. 为 GC 定义的系统参数

所以,请使用 GC 参数更新您的问题。

我建议您首先使用“-XX:-PrintGCDetails”打印 GC 详细信息,并使用以下命令生成堆转储文件:-XX:HeapDumpPath=./java_pid.hprof

这将有助于我们评估上述第 1 点和第 2 点。 更改 GC 算法有很多权衡,必须根据具体情况确定正确的算法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 2016-01-14
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多