4

我们正在 DEV 环境中对 Java 1.6 应用程序进行负载测试。JVM 堆分配为 2Gb,-Xms2048m -Xmx2048m。在负载测试下,应用运行流畅,从不使用超过 1.25Gb 的堆,垃圾回收完全正常。

在我们的 UAT 环境中,我们使用相同的参数运行负载测试,唯一的区别是 JVM,它分配了 4Gb,-Xms4096m -Xmx4096m,否则,硬件与 DEV 完全相同。但是在负载测试期间,性能非常糟糕,应用程序几乎耗尽了整个堆,并且垃圾收集猖獗。

我们一遍又一遍地运行这些测试,消除了所有可能影响性能的症状,但结果是一样的。在什么情况下会出现这种情况?

4

3 回答 3

5

您的应用程序在生产环境和 UAT 环境中有所不同。

从症状来看,(IMO)不太可能是硬件、操作系统性能调优或JVM版本的差异。不用说,这不太可能是由于应用程序具有更多内存。

(您的应用程序可能会做一些奇怪的事情并不是不可想象的......比如根据最大堆大小调整某些数据结构的大小并计算错误。但我认为您会意识到这种可能性,所以让我们暂时忽略它.)

这可能操作系统环境的差异有关;例如,不同版本的操作系统或某些应用程序、网络差异、语言环境差异等等。但最重要的是,当你的应用程序在 UAT 上运行时,有 99% 的把握肯定存在内存泄漏,而内存泄漏正是占用堆内存并使 GC 过载的原因。

我的建议是将其视为存储泄漏问题,并使用标准工具/技术来追踪问题的原因。在此过程中,您很可能能够弄清楚为什么这只发生在您的 UAT 上。

于 2012-08-31T04:01:17.840 回答
1

罪魁祸首可能是垃圾收集,正常的“stop-the-world”类型的收集给我们带来了一些性能问题;服务器软件运行速度很慢,但服务器的负载也很低。最终我们发现有一个“stop-the-world”——垃圾收集器线程在某些情况下(操作产生大量垃圾)一直在运行整个软件。

转向并发垃圾收集缓解了启动参数的问题-XX:+UseParallelOldGC -XX:ParallelGCThreads=8。我们在测试和生产中“仅”使用 2gb 堆,但值得注意的是,GC 占用的时间会随着堆的增大而增加(即使您的软件从未真正使用过所有这些)。

您可能想从此处阅读有关不同垃圾收集器选项和调整的更多信息:Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning

此外,这个问题的答案可以提供一些帮助:Java very large heap sizes

于 2012-08-31T04:23:31.090 回答
1

分析这两台机器上的堆转储并了解在这两个环境中以不同方式消耗堆的原因是值得的。直方图会有所帮助。

于 2012-08-31T06:45:01.563 回答