JVM性能在随机时间后会下降



简而言之,我遇到了一个性能问题,它一次"随机"出现在1个JVM中,以前可能已经运行了好几天,但我似乎找不到根本原因。我倾向于吃一些东西,但一直没能找到。

我已经把我能想到的一切都查了一遍,任何建议都会很棒!

(我有Jprofiler、yourkit和jvisualvm可供我使用,我试着用它们全部运行,并在JVM中运行比较)

设置如下。我们在大量使用的测试环境中运行了40个JVM(每台硬件机器运行10个JVM)。它们使用一种名为UltraESB(2.3.0)的开源产品,该产品利用线程池进行异步请求/回复处理,但在我们的案例中,是基于无状态标头的JMS消息路由。在我们的开发环境中,我们有一个不那么重但仍然常用的设置,我们从未见过这个问题。

因此,我们经常看到小GC(每几分钟一次),很少看到大GC(一天左右一次)。我们在centos 6.7上使用热点Java 1.7_71(Haswell CPU错误已修复)

偶尔(对我来说似乎完全是随机的),其中一个JVM会开始表现不佳(我们有关于应用程序性能的监视器+度量)。在正常情况下,我们在<1毫秒。一旦我们遇到错误场景,我们就会开始看到数百(100-200)毫秒的处理时间。当我们在几周内运行这些JVM时,我们将看到几个表现不佳的JVM。回收会把东西清理干净,再过几天它们就会运转良好。当JVM出错时,我们开始看到它们的处理时间与遇到性能问题的其他实例(包括其他硬件上的实例)几乎完全相同。这并不奇怪,因为它们是完全相同的代码库和JMS负载平衡循环,所以它们处理的消息数量几乎相同。

我通过打开CPU性能评测触发了这种性能影响。查看图表:蓝色是一个很好的过程,直到我打开CPU跟踪,它开始执行糟糕的

有趣的是,即使在禁用了评测之后,糟糕的性能仍然存在。

我试着测量的东西

我所尝试过的一切都没有让我找到任何银弹。

GC监控-GC持续时间和CPU利用率在参考JVM和性能较差的JVM之间似乎是一致的。

GC启动选项:

GC_OPTS="-XX:+PrintGCDetails 
-XX:+UseG1GC 
-XX:MaxGCPauseMillis=100 
-XX:+ParallelRefProcEnabled 
-XX:+UnlockExperimentalVMOptions 
-XX:-ResizePLAB 
-XX:G1NewSizePercent=50 
-XX:G1MaxNewSizePercent=50 
-XX:+PrintAdaptiveSizePolicy 
-Xloggc:/logs/applogs/${instancename}/gc.${DATE}.log"

CPU采样JVM内部发生了太多事情,对我来说没有什么不同。打开它会产生问题,但并不总是取决于采样设置。

线程池使用情况Stats被导出为MBean,线程池(spring 3.2.4 ThreadPoolTaskExecutor)和使用中的线程似乎与其他性能良好的实例相同。

您可以尝试http://mevss.jku.at/AntTracks.它是一个研究JVM,记录您的内存行为。然后,它能够随着时间的推移显示堆属性,还可以基于跟踪在任何时间点离线可视化堆。该VM的构建对行为的影响尽可能小,因此不会像配置不好的采样那样扭曲应用程序行为。当然,只有当您期望内存/GC在您的问题中发挥作用时,这才有帮助。

当我们从Spring DMLC侦听器容器使用的线程池中分离工作线程池时,我们的问题消失了。仍然无法找到根本原因,但问题已经解决。

最新更新