简而言之,我有一个“随机”出现在1 JVM中的性能问题,这个问题可能已经运行了好几天,但我似乎无法找到根本原因。我倾向于吃掉线程池的东西,但却无法追踪它。
我已经完成了我能想到的所有事情来追踪这一点,任何建议都会很棒!
(我已经掌握了Jprofiler,yourkit和jvisualvm,并且我已尝试使用它们并在JVM中运行比较)
所以这是设置。 我们在频繁使用的测试环境中运行40个JVM(每个硬件机器10个)。他们使用名为UltraESB(2.3.0)的开源产品,利用线程池进行异步请求/回复处理,但在我们的案例中,基于无状态头的JMS消息路由。 我们的开发环境中设置较少但仍然常用,我们从未见过这个问题。
因此,我们看到非常频繁的小型GC(每隔几分钟一次),很少看到主要的GC(每天一次)。我们正在使用热点Java 1.7_71,在centos 6.7上(Haswell CPU bug被修补)
偶尔(看似完全随机给我)其中一个JVM开始表现不佳(我们有监控+应用程序性能指标)。在正常情况下,我们处理< 1ms的消息。一旦我们遇到错误情景,我们就会开始看到数百(100-200)毫秒的处理时间。当我们在几周内运行这些时,我们会看到几个表现不佳的JVM。一个回收清理东西,他们将运行好几天。当JVM出错时,我们开始看到它们与遇到性能问题的其他实例(包括其他硬件上的实例)的处理时间几乎完全相同。这并不奇怪,因为它们是完全相同的代码库和JMS负载平衡循环,因此它们处理几乎相同数量的消息。
我通过打开CPU性能分析来触发这种性能影响。 请参见图表:Blue was good process until I turned on CPU tracing and it started to perform poorly
有趣的是,即使在剖析被禁用后,表现仍然不佳。
我所尝试过的任何东西都没有指向任何银子弹。
GC监控 - GC持续时间和CPU利用率在参考和性能不佳的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里面发生了很多事情,对我来说没什么好处。打开此功能会导致问题,但并不总是取决于采样设置。
线程池使用 统计信息作为MBean导出,线程池(弹簧3.2.4 ThreadPoolTaskExecutor)和正在使用的线程看起来与其他执行良好的实例相同。
答案 0 :(得分:1)
您可以尝试http://mevss.jku.at/AntTracks。它是一个研究JVM,记录你的记忆行为。然后,它可以随时间显示堆属性,并且还可以根据跟踪在任何时间点离线显示堆。构建此VM的行为对行为的影响很小,因此不会像严重配置的采样那样扭曲应用程序行为。这当然只有在您期望内存/ GC在您的问题中发挥作用时才有用。
答案 1 :(得分:0)
当我们从Spring DMLC侦听器容器正在使用的线程池中拆分工作线程池时,我们的问题就消失了。仍然无法找到根本原因,但问题已经解决。