我们看到一个有趣的(虽然非常严重)我们的应用服务器问题:在某个时间点,运行我们的Web应用程序的JVM的CPU使用率开始上升并持续上升,直到应用程序最终变慢爬到爬行。解决此问题的唯一方法是重新启动应用程序服务器软件。
这让我想到一个简单的问题;我们可以做些什么来解决这个问题?
我考虑过使用VisualVM(或其他一些JVM监控工具),但他们能做的最好 - 在这种特殊情况下 - 是给我一个线程转储,它仍然不会告诉我什么在占用所有的CPU时间(除非我遗漏了什么)。
答案 0 :(得分:5)
你需要了解它在做什么?此问题的常见原因是可用内存不足。如果这不是原因,则需要CPU分析器。 VisualVM随JDK免费提供,可以为您完成。
只有您无法始终对应用程序进行概要分析
当发生这种情况时,您可以通过相隔几秒钟多次调用jstack
进行临时分析。您可以使用堆栈跟踪的diff
来帮助您找到可能繁忙且占用CPU的线程。
答案 1 :(得分:3)
如果正在执行Full GC,CPU消耗线程基本上是卡住或占用线程或GC活动。
如果您使用的是基于unix的环境,则执行以下操作将预览JVM线程的利用率。 (PID是jvm的进程ID。)
prstat -L -p <PID>
随后可以获取threaddump(kill -3),然后prstat和threadump可以共同相关,找到哪些线程正在使用高CPU。
线程转储中的nid对应于prstat输出中LWPID的HEX值。
Eg: LWPID = java/75 corresponds to nid = 0X4B
一旦在线程转储中找到CPU消耗线程,就会有指向调查应该开始的指针。
此外,运行分析器例如:Jprofiler将会有所帮助。
答案 2 :(得分:1)
CPU使用率过高的原因之一可能是因为正在执行Full GC。 您可以在此处http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/了解如何在jvm中监控GC。
如果没有GC活动,则需要在CPU使用率超过某个阈值时使用jstack多次(几秒钟(5-10))进行一次线程转储。您可以通过后台进程实现此目的,后台进程使用Unix top命令监视运行jvm的进程的CPU使用情况。
一旦线程转储可用,您就可以通过VisualVM或Samurai等分析器运行它们,这将有助于您缩小到根本原因