有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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的更多详细信息,请告诉我


共 (2) 个答案

  1. # 1 楼答案

    对于您的具体问题:

    1. 新一代和旧一代之间的默认比率可能取决于系统以及JVM确定的最佳值
    2. -XX:NewRatio=3指定新世代和旧世代之间的特定比率
    3. 如果JVM挂起且堆已满,那么它可能会被困在常量GC中

    听起来prod需要更多的内存。如果在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
    
  2. # 2 楼答案

    你需要获得更多的数据才能知道发生了什么,只有这样你才能知道需要修复什么。在我看来这意味着

    1. 获取关于垃圾收集器正在做什么的详细信息,这些参数是一个良好的开端(用一些首选路径和文件代替gc.log)

      -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:gc.log -verbose:gc

    2. 重复运行,在gc日志中扫描挂起的时间段&;用该输出发回

    3. <> LI> < P>考虑使用VisualCalc来查看输出(需要在服务器上运行JSTATD,一个解释如何完成这个设置的随机链接是this one),它是jvmstat的一部分,这是一个V的简单方法来查看堆中的各个世代大小(虽然可能不为6HR)<

    我还强烈建议你也读一些书,这样你就知道所有这些开关都指的是什么,否则你会盲目地尝试一些东西,而没有真正理解为什么一件事有用,另一件事没有。我将从oracle java 6 gc调优页面开始,你可以找到here

    我只会建议在你有了基线表现后改变选项。虽然说CompressedOops很可能是一场轻松的胜利,但你可能需要注意的是,从6u23开始,它就被默认为on

    最后,你应该考虑升级JVM,6U18有点提高,性能不断提高。p>

    each job will take 3 hours to complete and almost 6 jobs running one after another. Last job when running reaches 8GB max and getting hang in prod

    这些工作有关系吗?如果他们不在同一个数据集上工作,这听起来真的像是逐渐的内存泄漏。如果堆使用率不断上升,最终崩溃,那么就会出现内存泄漏。您应该考虑使用^ {CD3}}来捕获堆转储(虽然注释为13g堆,但它将是一个大文件,因此确保您有磁盘空间)。然后可以使用jhat查看当时堆上的内容