Java JVM CPU峰值故障排除

Java JVM CPU峰值故障排除,java,jvm,cpu-usage,tcserver,Java,Jvm,Cpu Usage,Tcserver,我们在我们的一个应用服务器上看到了一个有趣(尽管相当严重)的问题:在某个时间点,运行web应用程序的JVM的CPU使用率开始上升,并持续上升,直到应用程序最终减速到爬行状态。修复此问题的唯一方法是重新启动应用程序服务器软件 应用服务器:SpringTC服务器(由于服务器托管在其他地方,我目前不知道确切的版本) 应用程序:相对标准的Spring3Web应用程序(不过我们使用的是JVM中的EHCache) 这让我想到一个简单的问题;我们可以做些什么来解决这个问题 我曾考虑过使用VisualVM(

我们在我们的一个应用服务器上看到了一个有趣(尽管相当严重)的问题:在某个时间点,运行web应用程序的JVM的CPU使用率开始上升,并持续上升,直到应用程序最终减速到爬行状态。修复此问题的唯一方法是重新启动应用程序服务器软件

  • 应用服务器:SpringTC服务器(由于服务器托管在其他地方,我目前不知道确切的版本)
  • 应用程序:相对标准的Spring3Web应用程序(不过我们使用的是JVM中的EHCache)
这让我想到一个简单的问题;我们可以做些什么来解决这个问题


我曾考虑过使用VisualVM(或其他JVM监控工具),但他们能做的最好的事情——在这种特殊情况下——是给我一个线程转储,它仍然不会告诉我消耗了多少CPU时间(除非我遗漏了什么)。

你需要知道它在做什么吗?此问题的常见原因是可用内存不足。如果这不是原因,则需要CPU探查器。VisualVM随JDK免费提供,可以同时为您提供这两种功能

只有您不能一直分析应用程序


当这种情况发生时,您可以通过在几秒钟内多次调用
jstack
来进行特别的评测。您可以使用堆栈跟踪的
diff
来帮助您找到可能正忙且消耗CPU的线程。

CPU消耗线程基本上是卡住或占用的线程,或者如果正在执行完整GC,则GC活动

如果您在基于unix的环境中,那么执行以下命令将预览JVM线程的利用率。(PID是jvm的进程id)

一旦在线程转储中找到CPU消耗线程,就可以使用指向应该开始调查的位置的指针


此外,运行探查器(例如:Jprofiler)会很有帮助。

CPU使用率高的原因之一可能是因为正在执行完整的GC。 您可以在这里了解如何在jvm中监视GC

如果没有GC活动,那么当CPU使用率超过某个阈值时,需要在几秒钟(5-10)之间多次使用jstack进行线程转储。您可以通过后台进程来实现这一点,该进程使用unixtop命令监视运行jvm的进程的CPU使用情况


一旦线程转储可用,您就可以通过VisualVM或Samurai之类的探查器运行它们,这将帮助您缩小到根本原因

内存消耗是我们的第一个猜测,但事实上这是正常的(有很多空闲)。使用探查器是一个很好的建议,只是您不能一直对应用程序进行探查(到目前为止,这已经有两周没有发生)。
prstat -L -p <PID> 
Eg: LWPID = java/75 corresponds to nid = 0X4B