【问题标题】:Troubleshooting JVM CPU spikes对 JVM CPU 峰值进行故障排除
【发布时间】:2018-11-15 20:07:55
【问题描述】:

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

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

这让我想到了一个简单的问题;我们可以做些什么来解决这个问题?

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

【问题讨论】:

    标签: java jvm cpu-usage tcserver


    【解决方案1】:

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

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

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

    【讨论】:

    • 内存消耗是我们的第一个猜测,但实际上是正常的(有足够的余量)。使用分析器是一个很好的建议,只是你不能一直分析应用程序(直到现在这已经有 2 周没有发生了)。
    【解决方案2】:

    如果正在执行 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 会很有帮助。

    【讨论】:

      【解决方案3】:

      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 等分析器运行它们,这将帮助您缩小根本原因

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-02
        • 2011-02-07
        • 2013-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多