📢📢📢本篇博文主要学习博文https://javaguide.cn/java/jvm/jdk-monitoring-and-troubleshooting-tools.html#jps-%E6%9F%A5%E7%9C%8B%E6%89%80%E6%9C%89-java-%E8%BF%9B%E7%A8%8B和腾讯云技术专家成长之路的文章https://cloud.tencent.com/developer/column/95208。
在Java的JDK安装目录的bin目录下,存放了许多JDK工具,这些工具都是以xxx.exe结尾。
本篇博文并不对所有工具进行讲解,主要总结一下,下图中比较常用的几个工具:
工具 | 描述 |
---|---|
jps (JVM Process Status) | 类似 UNIX 的 ps 命令。用于查看所有 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息; |
jstat(JVM Statistics Monitoring Tool) | 用于收集 HotSpot 虚拟机各方面的运行数据; |
jinfo (Configuration Info for Java) | Configuration Info for Java,显示虚拟机配置信息; |
jmap (Memory Map for Java) | 生成堆转储快照; |
jhat (JVM Heap Dump Browser) | 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果; |
jstack (Stack Trace for Java) | 生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。 |
jps命令类似于 UNIX 的 ps 命令,主要用来查看所有 Java 进程,显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一 ID(Local Virtual Machine Identifier,LVMID)
如果你的电脑配置了Java环境的话,直接在DOS命令框中输入JPS命令即可:
如果没有配置环境,你也可以直接在你的JDK目录下的bin下进行访问:
jps命令使用格式:
jps [-q] [-mlvV] [hostid]
jps [help]
相关参数解释:
参数 | 描述 |
---|---|
q | 不显示主类名称、JAR文件名和传递给主方法的参数,只显示本地虚拟机唯一ID。 |
mlvV | 我们可以指定这些参数的任意组合。 |
m | 显示Java虚拟机启动时传递给main()方法的参数。 |
l | 显示主类的完整包名,如果进程执行的是JAR文件,也会显示JAR文件的完整路径。 |
v | 显示Java虚拟机启动时传递的JVM参数。 |
V | 不显示主类名称、JAR文件名和传递给主方法的参数,只显示本地虚拟机唯一ID。 |
hostid | 指定的远程主机,可以是ip地址和域名, 也可以指定具体协议,端口。如果不指定,则显示本机的Java虚拟机的进程信息。 |
help | 显示jps命令的帮助信息。 |
显示格式:
LVMID [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]
练习:
本地虚拟机唯一ID和操作系统的进程ID(PID,Process Identifier)是一致的,如果同时启动多个Java虚拟机进程,无法根据进程名称确定某个进程,我们就是使用jps命令显示主类名称的功能区分出来,下图的LVMID=10408
mlvV参数是可以组合使用的,如下:
jps可以连接远程的主机,查看远程主机的jps信息,下面显示连接失败。
jstat(JVM Statistics Monitoring Tool) 使用于监视虚拟机各种运行状态信息的命令行工具。 它可以显示本地或者远程(需要远程主机提供 RMI 支持)虚拟机进程中的类信息、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI,只提供了纯文本控制台环境的服务器上,它将是运行期间定位虚拟机性能问题的首选工具。
jstat 命令使用格式:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
比如 jstat -gc -h3 28241000 10表示分析进程 id 为 2824 的 gc 情况,每隔 1000ms打印一次记录,打印 10 次停止,每 3 行后打印指标头部。
例子代码:
查询程序运行的PID:
使用 jstat -gc -h3 28241000 10 命令分析进程2824的GC情况:
常见的 option 如下:
参数 | 描述 |
---|---|
-class | 显示 ClassLoader 的相关信息; |
-compiler | 显示 JIT 编译的相关信息; |
-gc | 显示与 GC 相关的堆信息; |
-gccapacity | 显示各个代的容量及使用情况; |
-gcnew | 显示新生代信息; |
-gcnewcapacity | 显示新生代大小与使用情况; |
-gcold | 显示老年代和永久代的行为统计,从jdk1.8开始,该选项仅表示老年代,因为永久代被移除了; |
-gcoldcapacity | 显示老年代的大小; |
-gcmetacapacity | 显示永久代大小,从jdk1.8开始,该选项不存在了,因为永久代被移除了; |
-gcutil | 显示垃圾收集信息; |
练习:
参数如下表所示:
参数 | 描述 |
---|---|
Loaded | 加载的类的数量。 |
Bytes | 加载的类所占用的字节数。 |
Unloaded | 卸载的类的数量。 |
Bytes | 卸载的类所占用的字节数。 |
Time | 执行类加载和卸载操作所花费的时间。 |
参数如下表所示:
参数 | 描述 |
---|---|
Compiled | 执行的编译任务的数量。 |
Failed | 执行编译任务失败的数量。 |
Invalid | 执行编译任务失效的数量。 |
Time | 执行编译任务所花费的时间。 |
FailedType | 上次编译失败的编译类型。 |
FailedMethod | 上次编译失败的类名和方法。 |
参数如下表所示:
参数 | 描述 |
---|---|
S0C | 年轻代中第一个Survivor区的容量,单位为KB。 |
S1C | 年轻代中第二个Survivor区的容量,单位为KB。 |
S0U | 年轻代中第一个Survivor区已使用大小,单位为KB。 |
S1U | 年轻代中第二个Survivor区已使用大小,单位为KB。 |
EC | 年轻代中Eden区的容量,单位为KB。 |
EU | 年轻代中Eden区已使用大小,单位为KB。 |
OC | 老年代的容量,单位为KB。 |
OU | 老年代已使用大小,单位为KB。 |
MC | 元空间的容量,单位为KB。 |
MU | 元空间已使用大小,单位为KB。 |
CCSC | 压缩类的容量,单位为KB。 |
CCSU | 压缩类已使用大小,单位为KB。 |
YGC | Young GC的次数。 |
YGCT | Young GC所用的时间。 |
FGC | Full GC的次数。 |
FGCT | Full GC的所用的时间。 |
GCT | GC的所用的总时间。 |
参数如下表所示:
参数 | 描述 |
---|---|
NGCMN | 年轻代最小的容量,单位为KB。 |
NGCMX | 年轻代最大的容量,单位为KB。 |
NGC | 当前年轻代的容量,单位为KB。 |
S0C | 年轻代中第一个Survivor区的容量,单位为KB。 |
S1C | 年轻代中第二个Survivor区的容量,单位为KB。 |
EC | 年轻代中Eden区的容量,单位为KB。 |
OGCMN | 老年代最小的容量,单位为KB。 |
OGCMX | 老年代最大的容量,单位为KB。 |
OGC | 当前老年代的容量,单位为KB。 |
OC | 当前老年代的容量,单位为KB。 |
MCMN | 元空间最小的容量,单位为KB。 |
MCMX | 元空间最大的容量,单位为KB。 |
MC | 当前元空间的容量,单位为KB。 |
CCSMN | 压缩类最小的容量,单位为KB。 |
CCSMX | 压缩类最大的容量,单位为KB。 |
CCSC | 当前压缩类的容量,单位为KB。 |
YGC | Young GC的次数。 |
FGC | Full GC的次数。 |
参数如下表所示:
参数 | 描述 |
---|---|
S0C | 年轻代中第一个Survivor区的容量,单位为KB。 |
S1C | 年轻代中第二个Survivor区的容量,单位为KB。 |
S0U | 年轻代中第一个Survivor区已使用大小,单位为KB。 |
S1U | 年轻代中第二个Survivor区已使用大小,单位为KB。 |
TT | 对象在年轻代存活的次数。 |
MTT | 对象在年轻代存活的最大次数 |
DSS | 期望的Survivor区大小,单位为KB。 |
EC | 年轻代中Eden区的容量,单位为KB。 |
EU | 年轻代中Eden区已使用大小,单位为KB。 |
YGC | Young GC的次数。 |
YGCT | Young GC所用的时间。 |
参数如下表所示:
参数 | 描述 |
---|---|
NGCMN | 年轻代最小的容量,单位为KB。 |
NGCMX | 年轻代最大的容量,单位为KB。 |
NGC | 当前年轻代的容量,单位为KB。 |
S0CMX | 年轻代中第一个Survivor区最大的容量,单位为KB。 |
S0C | 年轻代中第一个Survivor区的容量,单位为KB。 |
S1CMX | 年轻代中第二个Survivor区最大的容量,单位为KB。 |
S1C | 年轻代中第二个Survivor区的容量,单位为KB。 |
ECMX | 年轻代中Eden区最大的容量,单位为KB。 |
EC | 年轻代中Eden区的容量,单位为KB。 |
YGC | Young GC的次数。 |
FGC | Full GC的次数。 |
参数如下表所示:
参数 | 描述 |
---|---|
MC | 元空间的容量,单位为KB。 |
MU | 元空间已使用大小,单位为KB。 |
CCSC | 压缩类的容量,单位为KB。 |
CCSU | 压缩类已使用大小,单位为KB。 |
OC | 老年代的容量,单位为KB。 |
OU | 老年代已使用大小,单位为KB。 |
YGC | Young GC的次数。 |
FGC | Full GC的次数。 |
FGCT | Full GC的所用的时间。 |
GCT | GC的所用的总时间。 |
参数如下表所示:
参数 | 描述 |
---|---|
OGCMN | 老年代最小的容量,单位为KB。 |
OGCMX | 老年代最大的容量,单位为KB。 |
OGC | 当前老年代的容量,单位为KB。 |
OC | 当前老年代的容量,单位为KB。 |
YGC | Young GC的次数。 |
FGC | Full GC的次数。 |
FGCT | Full GC的所用的时间。 |
GCT | GC的所用的总时间。 |
参数如下表所示:
参数 | 描述 |
---|---|
MCMN | 元空间最小的容量,单位为KB。 |
MCMX | 元空间最大的容量,单位为KB。 |
MC | 当前元空间的容量,单位为KB。 |
CCSMN | 压缩类最小的容量,单位为KB。 |
CCSMX | 压缩类最大的容量,单位为KB。 |
YGC | Young GC的次数。 |
FGC | Full GC的次数。 |
FGCT | Full GC的所用的时间。 |
GCT | GC的所用的总时间。 |
参数如下表所示:
参数 | 描述 |
---|---|
S0 | 年轻代中第一个Survivor区使用大小占当前容量的百分比。 |
S1 | 年轻代中第二个Survivor区使用大小占当前容量的百分比。 |
E | Eden区使用大小占当前容量的百分比。 |
O | 老年代使用大小占当前容量的百分比。 |
M | 元空间使用大小占当前容量的百分比。 |
CCS | 压缩类使用大小占当前容量的百分比。 |
YGC | Young GC的次数。 |
YGCT | Young GC所用的时间。 |
FGC | Full GC的次数。 |
FGCT | Full GC的所用的时间。 |
GCT | GC的所用的总时间。 |
备注:上面的参数来源于这篇博文:https://cloud.tencent.com/developer/article/1985765
jinfo(Java Virtual Machine Configuration Information)是JDK提供的一个可以实时查看Java虚拟机各种配置参数和系统属性的命令行工具。使用jps命令的-v参数可以查看Java虚拟机启动时显式指定的配置参数,如果想查看没有显式指定的配置参数就可以使用jinfo命令进行查看。另外,jinfo命令还可以查询Java虚拟机进程的System.getProperties()的内容。在没有dbgeng.dll的Windows系统中,必须安装用于Windows的调试工具才能使jinfo命令正常工作,PATH环境变量应该包含jvm.dll的位置。
jinfo命令使用格式:
jinfo [option] pid
jinfo命令参数
option的参数如下表所示:
参数 | 描述 |
---|---|
-flag name | 显示指定名称对应的配置参数 |
-flag [+|-]name | 启用或禁用指定名称的参数 |
-flag name=value | 不需要重启Java虚拟机,修改指定名称的参数为指定的值。 |
-flags | 显示全部的配置参数 |
-sysprops | 以键值对的方式显示当前Java虚拟机的全部的系统属性 |
-h 和 -help | 显示jinfo命令的帮助信息 |
练习:
当然不是所有参数都可以这样修改的,比如并发垃圾收集器将使用的线程数(ConcGCThreads):
那么,有哪些配置参数是支持动态修改的呢?我们可以通过java -XX:+PrintFlagsInitial命令找到标记为manageable的配置参数,运行结果如下图所示:
使用java -XX:+PrintFlagsInitial | grep manageable命令
注意:Windows下无法使用grep命令,需要安装greo软件,并配置相应环境,你可以参照这篇博文:Windows系统中用查询字符串可以用grep命令吗?。
备注上面的相关参数来源于这篇博文:https://cloud.tencent.com/developer/article/1985769
jmap(Java Virtual Machine Memory Map)是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具。除此以外,jmap命令还可以查看finalize执行队列、Java堆和方法区的详细信息,比如空间使用率、当前使用的什么垃圾回收器、分代情况等等。和jinfo命令一样,在Windows系统上使用还是有一些限制的。在没有dbgeng.dll的Windows系统中,必须安装用于Windows的调试工具才能使jinfo命令正常工作,PATH环境变量应该包含jvm.dll的位置。
jmap命令语法:
jmap [options] pid
命令参数说明:
option的参数及其使用案例:
请参照这篇博文:https://cloud.tencent.com/developer/article/1985770?from=article.detail.1985769
jhat 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果。
生成heap dump 文件:
jhat分析 heapdump 文件:
游览器访问http://localhost:7000/ :
关于什么是heap dump文件
heap dump: heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况。HeapDump文件是指定时刻的Java堆栈的快照,是一种镜像文件,你可以通过这篇博文详细学习heap dump 文件https://www.jianshu.com/p/c34af977ade1。
jstack(Java Virtual Machine Stack Trace)是JDK提供的一个可以生成Java虚拟机当前时刻的线程快照信息的命令行工具。线程快照一般被称为threaddump或者javacore文件,是当前Java虚拟机中每个线程正在执行的Java线程、虚拟机内部线程和可选的本地方法堆栈帧的集合。对于每个方法栈帧,将会显示完整的类名、方法名、字节码索引(bytecode index,BCI)和行号。生成的线程快照可以用于定位线程出现长时间停顿的原因,比如:线程间死锁、死循环、请求外部资源被长时间挂起等等。
jstack 命令语法:
jstack [options] pid
命令参数说明:
option参数如下表所示:
参数 | 描述 |
---|---|
-F | 如果Java虚拟机进程由于进程挂起而没有任何响应,那么可以使用-F参数(仅在Oracle Solaris和Linux操作系统上游戏)强制显示线程快照信息。 |
-l | 如果使用-l参数,除了方法栈帧以外,jstack命令还会显示关于锁的附加信息,比如属于java.util.concurrent的ownable synchronizers列表。 |
-m | 如果使用-m参数,jstack命令将显示混合的栈帧信息,除了Java方法栈帧以外,还有本地方法栈帧。本地方法栈帧是C或C++编写的虚拟机代码或JNI/native代码。 |
-h 和 -help | 显示jstack命令的帮助信息。 |
option的参数的使用案例: