好的。首先我们需要明确一下使用Java诊断工具的目的,这些工具主要是用于排查和解决Java应用程序运行过程中的各种故障和问题。具体来说,在使用Java诊断工具前,应该根据问题类型选择合适的Java诊断工具,并认真阅读Java诊断工具的文档和使用说明。
以下是一些常用的Java诊断工具:
-
jps
命令:查询Java虚拟机上正在运行的进程信息。 -
jstack
命令:生成Java虚拟机当前时刻的线程快照,用于检测死锁、不响应等问题。 -
jmap
命令:生成Java虚拟机当前时刻的内存快照,用于分析内存泄漏、缓存问题等。
接下来,我们以jstack
和jmap
两个常用工具为例子进行详细的介绍与演示。
如何使用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. 示例
具体使用步骤如下:
- 首先,使用
jps
查找Java虚拟机进程pid,如下:
[john@localhost ~]$ jps
27615 Bootstrap
28412 Jps
可以看到当前Java虚拟机进程号为27615。
- 然后,使用
jmap
命令生成内存快照,并将快照保存至指定文件中:
[john@localhost ~]$ jmap -dump:format=b,file=heap.bin 27615
其中,-dump:format=b,file=<FILENAME>
表示将内存快照保存到指定的文件中,27615
表示Java虚拟机进程号。执行以上命令后,在当前目录下可以看到生成的名为heap.bin
的内存快照文件。
- 分析内存快照
分析内存快照可以使用一些工具,例如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
命令时常用的操作步骤。除了jstack
和jmap
,Java虚拟机提供了更多的诊断工具,例如jstat
、jconsole
、visualvm
等,不同工具有不同的应用场景和使用方法。建议根据实际情况选择合适的Java诊断工具,有助于更快、更准确地解决Java程序问题。