如何跟踪java程序?

如何跟踪java程序?

作为一名系统管理员,我有时会遇到这样的情况:程序行为异常,但根本不会创建错误或创建无意义的错误消息。

过去——在java出现之前——有两种应对措施:

  1. 如果没有其他帮助 - RTFM ;-)
  2. 如果 1. 没有帮助 - 跟踪系统调用并查看发生了什么

我通常使用strace -fLinux 来完成此任务(其他操作系统也有类似的跟踪工具)。现在,虽然这通常适用于任何老式程序,但当在爪哇-过程。有如此多的系统调用看似与任何实际操作无关,因此在这样的转储中进行搜索非常糟糕。

有没有更好的方法来做到这一点(如果源代码不可用)?

答案1

正如 ckhan 提到的,jstack它很棒,因为它提供了 JVM 中所有活动线程的完整堆栈跟踪。可以使用 SIGQUIT 在 JVM 的 stderr 上获得相同的结果。

另一个有用的工具是jmap它可以使用进程的 PID 从 JVM 进程中获取堆转储:

jmap -dump:file=/tmp/heap.hprof $PID

此堆转储可以加载到诸如visualvm(现在是标准 Oracle java sdk 安装的一部分,名为 jvisualvm)之类的工具中。此外,VisualVM 可以连接到正在运行的 JVM 并显示有关 JVM 的信息,包括显示内部 CPU 使用情况、线程计数和堆使用情况的图表 - 非常适合跟踪泄漏。

另一个工具,jstat可以在一段时间内收集 JVM 的垃圾收集统计信息,就像使用数字参数(例如vmstat 3)运行时的 vmstat 一样。

最后,可以使用 Java 代理在加载时对所有对象的所有方法推送检测。图书馆javassist可以帮助您轻松做到这一点。因此,添加自己的跟踪是可行的。困难的部分是找到一种方法,仅在您需要时而不是始终获取跟踪输出,这可能会减慢 JVM 的速度。有一个名为的程序dtrace以这样的方式工作。我尝试过,但不是很成功。请注意,代理无法检测所有类,因为引导 JVM 所需的类会在代理检测之前加载,然后向这些类添加检测就为时已晚。

我的建议- 从 VisualVM 开始,看看它是否告诉您需要了解什么,因为它可以显示 JVM 的当前线程和重要统计信息。

答案2

同样,在调试 Linux 系统上出错的程序时,您可以使用类似的工具来调试系统上正在运行的 JVM。

工具#1 - jvmtop

类似于top,您可以使用虚拟机顶部查看系统上正在运行的 JVM 中的类的情况。安装后,您可以像这样调用它:

$ jvmtop.sh

其输出的样式与该工具类似top

 JvmTop 0.8.0 alpha   amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
 http://code.google.com/p/jvmtop

  PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46

工具 #2 - jvmmonitor

另一种选择是使用虚拟机监控器。 JVM Monitor 是一个与 Eclipse 集成的 Java 分析器,用于监视 Java 应用程序的 CPU、线程和内存使用情况。您可以使用它自动查找本地主机上正在运行的 JVM,也可以使用 port@host 连接到远程 JVM。

jvmmonitor 的 ss

工具 #3 - visualvm

视觉虚拟机可能是调试 JVM 问题时需要使用的“工具”。它的功能集非常深入,您可以非常深入地了解其内部结构。

分析应用程序性能或分析内存分配:

VisualVM #2 的 SS

获取并显示线程转储:

VisualVM #3 的 SS

参考

答案3

考虑jstack。不太匹配strace,更像是pstack- 模拟,但至少会给你及时的快照图片。如果需要的话,可以将它们串在一起以获得粗略的痕迹。

另请参阅这篇 SO 文章中的建议:https://stackoverflow.com/questions/1025681/call-trace-in-java

答案4

建议您尝试一下杰克游戏,这是一个 JVM 跟踪工具,允许您跟踪方法的进入和退出,而无需更改代码或重新部署。

相关内容