作为系统管理员,我有时会遇到这样的情况,即程序运行异常,而根本不会产生错误或产生无意义的错误消息。
过去 - 在 java 出现之前 - 有两种对策:
我通常strace -f在 Linux 上用于此任务(其他操作系统具有类似的跟踪工具)。现在,虽然这通常适用于任何老式程序,但在java进程上执行相同操作时,跟踪会变得非常模糊。有太多看起来与任何实际操作无关的系统调用,在这样的转储中搜索是很糟糕的。
有没有更好的方法来做到这一点(如果源代码不可用)?
ash*_*ash 18
正如 ckhan 所提到的,jstack它很棒,因为它提供了 JVM 中所有活动线程的完整堆栈跟踪。同样可以使用 SIGQUIT 在 JVM 的 stderr 上获得。
另一个有用的工具是jmap它可以使用进程的 PID 从 JVM 进程中获取堆转储:
jmap -dump:file=/tmp/heap.hprof $PID
Run Code Online (Sandbox Code Playgroud)
这个堆转储可以加载到类似的工具中 visualvm(现在是标准 Oracle java sdk 安装的一部分,名为 jvisualvm)。此外,VisualVM 可以连接到正在运行的 JVM 并显示有关 JVM 的信息,包括显示内部 CPU 使用率、线程计数和堆使用率的图表 - 非常适合跟踪泄漏。
另一个工具jstat可以在一段时间内为 JVM 收集垃圾收集统计信息,这与使用数字参数(例如vmstat 3)运行时的 vmstat 非常相似。
最后,可以使用 Java 代理在加载时对所有对象的所有方法推送检测。图书馆javassist可以帮助使这很容易做到。因此,添加您自己的跟踪是可行的。困难的部分是找到一种方法,仅在您需要时而不是一直获取跟踪输出,这可能会减慢 JVM 的速度。有一个名为的程序dtrace以这样的方式工作。我试过了,但不是很成功。请注意,代理无法检测所有类,因为引导 JVM 所需的类在代理可以检测之前加载,然后向这些类添加检测为时已晚。
我的建议- 从 VisualVM 开始,看看它是否会告诉您需要了解的内容,因为它可以显示 JVM 的当前线程和重要统计信息。
slm*_*slm 11
在调试在 Linux 系统上出错的程序时,同样徒劳无功,您可以使用类似的工具来调试系统上正在运行的 JVM。
与 类似top,您可以使用jvmtop查看系统上正在运行的 JVM 中的类。安装后,您可以像这样调用它:
$ jvmtop.sh
Run Code Online (Sandbox Code Playgroud)
它的输出风格类似工具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
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用jvmmonitor。JVM Monitor 是一个与 Eclipse 集成的 Java 分析器,用于监控 Java 应用程序的 CPU、线程和内存使用情况。您可以使用它来自动查找本地主机上正在运行的 JVM,也可以使用 port@host 连接到远程 JVM。

在调试 JVM 问题时,visualvm可能是“工具”。它的功能集非常深入,您可以非常深入地了解内部结构。
分析应用程序性能或分析内存分配:

获取并显示线程转储:

| 归档时间: |
|
| 查看次数: |
47740 次 |
| 最近记录: |