5

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

  • 应用服务器:Spring tc Server(因为服务器托管在别处,目前不知道具体版本)
  • 应用程序:相对标准的 Spring 3 Web 应用程序(尽管我们确实使用了一个 in-JVM EHCache)

这给我带来了一个简单的问题;我们能做些什么来解决这个问题?

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

4

3 回答 3

5

你需要弄清楚它在做什么?此问题的一个常见原因是可用内存不足。如果这不是原因,则需要 CPU 分析器。VisualVM 随 JDK 一起免费提供,并且可以为您做这两件事。

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

jstack发生这种情况时,您可以通过每隔几秒钟调用多次来进行临时分析。您可以使用diff堆栈跟踪来帮助您找到可能很忙且消耗 CPU 的线程。

于 2013-01-30T11:10:21.200 回答
4

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

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

prstat -L -p <PID> 

随后可以进行线程转储(kill -3),然后可以将 prstat 和线程转储关联起来以查找哪些线程正在使用高 CPU。

线程转储中的 nid 对应于 prstat 输出中 LWPID 的 HEX 值。

Eg: LWPID = java/75 corresponds to nid = 0X4B

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

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

于 2013-01-30T11:18:12.463 回答
1

CPU 使用率高的原因之一可能是因为正在执行 Full GC。您可以在这里查看http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/以了解如何在 jvm 中监控 GC。

如果没有 GC 活动,当您的 CPU 使用率超过某个阈值时,您需要每隔几秒 (5-10) 多次使用 jstack 进行线程转储。您可以通过后台进程来实现这一点,该进程使用 Unix top 命令监控运行 jvm 的进程的 CPU 使用率。

一旦线程转储可用,您可以通过 VisualVM 或 Samurai 等分析器运行它们,这将帮助您缩小到根本原因

于 2014-10-07T17:54:13.787 回答