java JVM终身/旧代已达到限制&服务器挂起
我们的应用程序需要非常大的内存,因为它处理非常大的数据。因此,我们将最大堆大小增加到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中,我们将max PS Old Gen(堆内存)分配为8.67GB,而在Prod中仅为8GB
在Prod中,旧的Gen堆达到8GB,挂在那里,web URL变得不可访问。服务器正在关闭。 但在QA中,它也达到了8.67GB,但执行了完整的GC,并返回到6.5GB或其他。在这里,它不会被绞死
我们无法找到解决方案,因为两个盒子上的环境和配置都是相同的
我有三个问题
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 楼答案
对于您的具体问题:
-XX:NewRatio=3
指定新世代和旧世代之间的特定比率李>听起来prod需要更多的内存。如果在QA上请求完成,那么可能只需要额外的0.67GB。但这似乎并没有给你留下多少空间。你在QA上运行的测试和在prod上运行的测试一样吗
因为您使用的是12GB,所以必须使用64位。使用
-XX:+UseCompressedOops
选项可以节省64位寻址的内存开销。它通常会节省40%的内存,所以12GB的内存会更大根据您正在做的事情,并发收集器可能也会更好,尤其是为了减少较长的GC暂停时间。我建议尝试这些选项,因为我发现它们效果很好:
# 2 楼答案
你需要获得更多的数据才能知道发生了什么,只有这样你才能知道需要修复什么。在我看来这意味着
获取关于垃圾收集器正在做什么的详细信息,这些参数是一个良好的开端(用一些首选路径和文件代替gc.log)
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:gc.log -verbose:gc
重复运行,在gc日志中扫描挂起的时间段&;用该输出发回
我还强烈建议你也读一些书,这样你就知道所有这些开关都指的是什么,否则你会盲目地尝试一些东西,而没有真正理解为什么一件事有用,另一件事没有。我将从oracle java 6 gc调优页面开始,你可以找到here
我只会建议在你有了基线表现后改变选项。虽然说
最后,你应该考虑升级JVM,6U18有点提高,性能不断提高。p>CompressedOops
很可能是一场轻松的胜利,但你可能需要注意的是,从6u23开始,它就被默认为on这些工作有关系吗?如果他们不在同一个数据集上工作,这听起来真的像是逐渐的内存泄漏。如果堆使用率不断上升,最终崩溃,那么就会出现内存泄漏。您应该考虑使用^ {CD3}}来捕获堆转储(虽然注释为13g堆,但它将是一个大文件,因此确保您有磁盘空间)。然后可以使用jhat查看当时堆上的内容