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

rak*_*sja 22 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
Run Code Online (Sandbox Code Playgroud)

我们在质量保证和产品中有以上环境和配置.在QA中,我们将最大PS旧Gen(堆内存)分配为8.67GB,而在Prod中它仅为8GB.

在Prod中,对于特定的工作,Old Gen Heap达到8GB,挂起并且Web URL无法访问.服务器正在崩溃.但在QA中它也达到了8.67GB,但是执行了完整的GC并且它恢复到6.5GB或者其他东西.这里没有被绞死.

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

我这里有3个问题,

最大堆的2/3将分配给旧/终身.如果是这样的话,为什么它在一个地方是8GB而在另一个地方是8.67GB?

在这种情况下如何为新手和终身提供有效比率(12GB)?

为什么它在一个地方完全GCed而不在另一个地方?

任何帮助都会非常明显.谢谢.

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

Whi*_*g34 22

针对您的具体问题:

  1. 新旧代之间的默认比率取决于系统以及JVM确定的最佳选择.
  2. 指定新旧代之间的特定比例-XX:NewRatio=3.
  3. 如果你的JVM挂起并且堆已满,那么它可能会停留在持续的GC上.

听起来你需要更多的内存来生产.如果在QA上请求结束,则可能需要额外的0.67GB.这似乎并没有给你留下太多空间.您是否在生产质量保证上运行相同的测试?

由于您使用的是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
Run Code Online (Sandbox Code Playgroud)

  • @techastute:很高兴听到,很高兴它有所帮助.比率规格不一定是必需的.这只是一种方便的方法,可以指定一个合理的默认值,该默认值对于相同的堆大小是一致的,并且适用于不同的大堆大小.我推荐的所有其他选项都专注于消除长GC暂停.对于我们的场景,我们发现并发收集器经常回落到完整的GC和其他长时间暂停而没有调整.这些选项是很长时间内持续繁重网络流量的许多基准测试和生产实验的结果.因人而异. (3认同)
  • 我们已经完成了许多具有24GB堆的大规模基准测试.`-XX:+ UseCompressedOops`选项不会显着降低性能.如果你处于有限的内存状态,那么它肯定可以提高性能.特别是如果它可以避免内存不足或耗尽,就像你的情况一样.对于12GB,它实际上就像是在没有`-XX:+ UseCompressedOops`的情况下给它16GB. (2认同)
  • `-XX:+ UseCompressedOops`完成了这个伎俩.我只添加了这个额外的参数,它现在正在使用12GB堆本身.在8GB以上的旧版本中,它的进程和频繁的GC /压缩发生,将其降低到6.5GB.如果您仍然坚持我们制定比率规格,那么请解释一下.谢谢. (2认同)