我们的应用程序需要非常大的内存,因为它处理非常大的数据。因此,我们将最大堆大小增加到 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 的更多详细信息,请告诉我。
最佳答案
对于您的具体问题:
- 新老代之间的默认比例可能取决于系统以及 JVM 确定的最佳值。
- 使用
-XX:NewRatio=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/