如何使用Java诊断工具?

  • Post category:Java

好的。首先我们需要明确一下使用Java诊断工具的目的,这些工具主要是用于排查和解决Java应用程序运行过程中的各种故障和问题。具体来说,在使用Java诊断工具前,应该根据问题类型选择合适的Java诊断工具,并认真阅读Java诊断工具的文档和使用说明。

以下是一些常用的Java诊断工具:

  1. jps命令:查询Java虚拟机上正在运行的进程信息。

  2. jstack命令:生成Java虚拟机当前时刻的线程快照,用于检测死锁、不响应等问题。

  3. jmap命令:生成Java虚拟机当前时刻的内存快照,用于分析内存泄漏、缓存问题等。

接下来,我们以jstackjmap两个常用工具为例子进行详细的介绍与演示。

如何使用jstack命令?

1. 用途

jstack 命令生成Java虚拟机堆栈信息,用于分析引发死锁、超时、线程挂起等线程性能相关问题,也可以用于对线程进行快速的分析.

2. 命令格式

jstack PID

其中 PID 表示JVM进程号,使用jps命令可以获取JVM进程号。可以将jstack 命令输出的结果保存到文件中进行分析:

jstack -F pid -l > jstack.log

输出文件中-F表示强制进行栈帧信息记录,如果线程处于假死状态的情况下可以使用该参数;-l表示除了线程堆栈之外,还将显示关于锁定信息的额外信息。

3. 示例

首先,使用jps查找JVM进程号,如下示例所示:

[john@localhost ~]$ jps
27615 Bootstrap
28412 Jps

其中,可以看到当前只有一个正在运行的Java进程Bootstrap,其进程号为27615。现在使用jstack命令查看该进程的线程信息:

[john@localhost ~]$ jstack 27615

输出结果如下:

Attaching to process ID 27615, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.192-b12
Deadlock Detection:

No deadlocks found.

Thread 3227: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
 - java.lang.Object.wait() @bci=2, line=502 (Compiled frame)
 - hudson.remoting.Request.call() @bci=54, line=129 (Compiled frame)
 - hudson.remoting.Channel.call(java.lang.Object, hudson.remoting.Callable) @bci=127, line=752 (Compiled frame)
 - hudson.FilePath.act(hudson.FilePath$FileCallable) @bci=82, line=1079 (Compiled frame)
 - hudson.FilePath.act(hudson.FilePath$FileCallable) @bci=1, line=1068 (Compiled frame)
 - hudson.nodes.AbstractFileNode$3.run() @bci=9, line=229 (Compiled frame)
 - java.util.concurrent.Executors$RunnableAdapter.call() @bci=4, line=511 (Compiled frame)
 - java.util.concurrent.FutureTask.run() @bci=42, line=266 (Compiled frame)
 - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1142 (Compiled frame)
 - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=617 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=748 (Interpreted frame)

可以看到,该进程的线程堆栈信息被输出到了终端中。

如何使用jmap命令?

1. 用途

jmap 命令生成Java虚拟机内存快照,可以用于分析引发内存泄漏、heap size,GC过程等内存性能相关问题。

2. 命令格式

jmap -dump:format=b,file=<FILENAME> <PID>

其中,-dump:format=b,file=<FILENAME> 表示将内存快照保存到指定的文件中,PID 表示Java虚拟机进程号。

3. 示例

具体使用步骤如下:

  1. 首先,使用jps查找Java虚拟机进程pid,如下:
[john@localhost ~]$ jps
27615 Bootstrap
28412 Jps

可以看到当前Java虚拟机进程号为27615。

  1. 然后,使用jmap命令生成内存快照,并将快照保存至指定文件中:
[john@localhost ~]$ jmap -dump:format=b,file=heap.bin 27615

其中,-dump:format=b,file=<FILENAME> 表示将内存快照保存到指定的文件中,27615表示Java虚拟机进程号。执行以上命令后,在当前目录下可以看到生成的名为heap.bin的内存快照文件。

  1. 分析内存快照

分析内存快照可以使用一些工具,例如jvisualvm工具和Eclipse自带的Memory Analyzer工具。这里以jvisualvm工具为例,步骤如下:

  • 启动jvisualvm工具,选择菜单栏上的”File” -> “Load…” -> “heap.bin”,加载刚才生成的内存快照文件。

  • 在jvisualvm窗口中展开”Loading…”,然后找到一个名为”java.lang.Class”的类,右键点击该类,选择”Run OQL Query”。

  • 在弹出的对话框中输入如下查询语句:

select heap.objectsOfClass("java.lang.String")

这个查询会返回所有Java Heap中的字符串对象。

  • 通过查询字符串对象的数量,可以快速判断该应用程序是否存在内存泄露等问题。

以上就是使用jmap命令时常用的操作步骤。除了jstackjmap,Java虚拟机提供了更多的诊断工具,例如jstatjconsolevisualvm等,不同工具有不同的应用场景和使用方法。建议根据实际情况选择合适的Java诊断工具,有助于更快、更准确地解决Java程序问题。