显示奇怪行为的视觉虚拟机
Visual VM showing strange behavior
我正在使用 VisualVM 监视我的 JBoss 实例。我也附上了它的截图。
问题是在我重启 JBoss 实例后,OS 上的 CPU 开始变高。负载可以高达 40,top 命令中的 JAVA 进程显示高达 300% 的使用率。
这会继续降低前端的应用程序速度。
VisualVM 显示 CPU 很高并且线程数也在增加。
我怎样才能进一步找到这个问题的根本原因?
一个好的开始是生成堆转储,并使用堆转储分析器工具来查看引擎盖下发生的事情,并使用 VisualVM 浏览它
一些适合您的免费替代品是 Eclipse MAT or IBM HeapAnalyzer
了解增加线程数相当容易。捕获几个 theaddumps 并比较创建的新线程。
要获得高 CPU 利用率,您必须使用 Visual VM(如果此信息可用)或本机系统监视工具来检测导致此问题的线程。您应该能够将线程 ID 映射到 threaddump 中的堆栈跟踪以查看真正的原因。
当谈到高 CPU 使用率时,我通常会寻找两件事:
- 频繁的 GC 消耗 CPU
- 线程消耗 CPU
要进一步诊断#1,启用 GC 日志记录可能是最好的方法。但是,您也可以使用 jstat:
jstat -gc PID 60s
上述命令将每 60 秒从 JVM 收集内存使用情况和垃圾收集详细信息。在调试环境中,60s 应该可以,但在生产环境中,3600s 应该足够了。 jstat 重量很轻,不会产生任何不利影响。输出将帮助您了解是否存在频繁的 GC (major/minor)。频繁的主要收集肯定是一个问题(它会暂停应用程序),但是,非常频繁的次要收集也可能导致高 CPU(应用程序过于频繁地创建太多垃圾)。如果是这种情况,您可能需要一个 head dump 并且您需要了解应用程序的内存使用详细信息,但在此之前不需要。请记住,捕获堆转储可能 "hang" 您的应用程序(我不建议在生产中使用它,除非您可以在捕获数据后立即重新启动应用程序)。
为了诊断 #2,"top" 提供了一个选项 ("H") 来检查单个线程消耗的 CPU。这将(实时)指出消耗 CPU 的应用程序线程。另外(正如其他人所建议的那样),以 10 秒的间隔捕获 5/6 个线程转储。查找处于 RUNNABLE 状态的线程。这些是正在工作并因此占用 CPU 的线程。同一个(一组)线程是否在多个转储中停留在 Runnable 状态?可能你遇到了问题。
希望这对您有所帮助。祝你好运!
是的,但由于 2 个问题,我们很难从线程转储中找到它。
1. CPU 利用率在 15-20 分钟内从 20% 迅速增加到 90%。我们无法在其他环境中这样做。
2. 当我们进行线程转储时,可能导致问题的实际线程已经完成,我们发现其他正在等待资源的线程。
有没有其他方法可以在服务器端配置或检查?
我正在使用 VisualVM 监视我的 JBoss 实例。我也附上了它的截图。
问题是在我重启 JBoss 实例后,OS 上的 CPU 开始变高。负载可以高达 40,top 命令中的 JAVA 进程显示高达 300% 的使用率。
这会继续降低前端的应用程序速度。
VisualVM 显示 CPU 很高并且线程数也在增加。
我怎样才能进一步找到这个问题的根本原因?
一个好的开始是生成堆转储,并使用堆转储分析器工具来查看引擎盖下发生的事情,并使用 VisualVM 浏览它
一些适合您的免费替代品是 Eclipse MAT or IBM HeapAnalyzer
了解增加线程数相当容易。捕获几个 theaddumps 并比较创建的新线程。
要获得高 CPU 利用率,您必须使用 Visual VM(如果此信息可用)或本机系统监视工具来检测导致此问题的线程。您应该能够将线程 ID 映射到 threaddump 中的堆栈跟踪以查看真正的原因。
当谈到高 CPU 使用率时,我通常会寻找两件事:
- 频繁的 GC 消耗 CPU
- 线程消耗 CPU
要进一步诊断#1,启用 GC 日志记录可能是最好的方法。但是,您也可以使用 jstat:
jstat -gc PID 60s
上述命令将每 60 秒从 JVM 收集内存使用情况和垃圾收集详细信息。在调试环境中,60s 应该可以,但在生产环境中,3600s 应该足够了。 jstat 重量很轻,不会产生任何不利影响。输出将帮助您了解是否存在频繁的 GC (major/minor)。频繁的主要收集肯定是一个问题(它会暂停应用程序),但是,非常频繁的次要收集也可能导致高 CPU(应用程序过于频繁地创建太多垃圾)。如果是这种情况,您可能需要一个 head dump 并且您需要了解应用程序的内存使用详细信息,但在此之前不需要。请记住,捕获堆转储可能 "hang" 您的应用程序(我不建议在生产中使用它,除非您可以在捕获数据后立即重新启动应用程序)。
为了诊断 #2,"top" 提供了一个选项 ("H") 来检查单个线程消耗的 CPU。这将(实时)指出消耗 CPU 的应用程序线程。另外(正如其他人所建议的那样),以 10 秒的间隔捕获 5/6 个线程转储。查找处于 RUNNABLE 状态的线程。这些是正在工作并因此占用 CPU 的线程。同一个(一组)线程是否在多个转储中停留在 Runnable 状态?可能你遇到了问题。
希望这对您有所帮助。祝你好运!
是的,但由于 2 个问题,我们很难从线程转储中找到它。 1. CPU 利用率在 15-20 分钟内从 20% 迅速增加到 90%。我们无法在其他环境中这样做。 2. 当我们进行线程转储时,可能导致问题的实际线程已经完成,我们发现其他正在等待资源的线程。
有没有其他方法可以在服务器端配置或检查?