java - JVM Tenured/Old gen 达到限制和服务器挂起

标签 java jboss garbage-collection jvm heap-memory

我们的应用程序需要非常大的内存,因为它处理非常大的数据。因此,我们将最大堆大小增加到 12GB (-Xmx)。

以下是环境详情

OS - Linux 2.6.18-164.11.1.el5    
JBoss - 5.0.0.GA
VM Version - 16.0-b13 Sun JVM
JDK - 1.6.0_18

我们的 QA 和产品中有上述环境和配置。 在 QA 中,我们将最大 PS Old Gen(堆内存)分配为 8.67GB,而在 Prod 中仅为 8GB。

在特定作业的 Prod 中,旧代堆达到 8GB,卡在那里并且 Web URL 变得无法访问。服务器正在停机。 但在 QA 中,它也达到了 8.67GB,但执行了完整的 GC,它又回到了 6.5GB 或其他东西。在这里它不会被绞死。

我们无法找到解决方案,因为两个盒子上的环境和配置都是相同的。

我这里有 3 个问题,

2/3rd of max heap will be allocated to old/tenured gen. If that is the case why it is 8GB in one place and 8.67GB in another place?

How to provide a valid ratio for New and Tenure in this case(12GB)?

Why it is full GCed in one place and not in the other?

任何帮助都会非常显着。谢谢。

如果您需要有关 env 或 conf 的更多详细信息,请告诉我。

最佳答案

对于您的具体问题:

  1. 新老代之间的默认比例可能取决于系统以及 JVM 确定的最佳值。
  2. 使用 -XX:NewRatio=3 指定新旧世代之间的特定比率。
  3. 如果您的 JVM 挂起并且堆已满,则可能会卡在进行持续 GC。

听起来您需要更多内存来进行生产。如果在 QA 上请求完成,那么可能只需要额外的 0.67GB。不过,这似乎并没有给你留下太多的空间。您是否在 QA 上运行与 prod 上相同的测试?

由于您使用的是 12GB,因此您必须使用 64 位。您可以使用 -XX:+UseCompressedOops 选项节省 64 位寻址的内存开销。它通常会节省 40% 的内存,因此您的 12GB 会更进一步。

根据您正在执行的操作,并发收集器也可能会更好,尤其是在减少较长的 GC 暂停时间方面。我建议尝试这些选项,因为我发现它们效果很好:

-Xmx12g -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC
-XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled
-XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68

关于java - JVM Tenured/Old gen 达到限制和服务器挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5939304/

相关文章:

Hibernate 4 (Jboss as 7) 无法自动检测实体并插入 PersistenceUnit,导致 `unknown entity` 异常

c# - Java 垃圾回收

garbage-collection - 如何在过多的 GC 中尽快 OOM?

java - 等待 get 请求在 Selenium 中完成

java - 使用需要对象作为参数的compareTo 来比较字符串

java - Gradle 同步失败 : Could not load class 'org.jetbrains.kotlin.gradle.KotlinGradleModelImpl'

多次插入的 Java 事务不回滚

spring - 缓存最佳实践 java

security - 哪些 JBoss 版本(如果有)受到 Heartbleed 漏洞的影响?

Java - LinkedList 的自动垃圾回收是如何工作的?