JDK工具详解(1)
本内容基于 JDK 11,如与读者不一致,请自行查阅其他资料。
语法中:[] 表示可选项 ,<>表示必填项, [<>] 选中该可选项后其中的内容为必填,[:]选中该可选项后内容可不填
一.jps 工具
linux/unix平台上简单察看当前java进程的一些简单情况。
很多人都是用过unix系统里的ps命令,这个命令主要是用来显示当前系统的进程情况,有哪些进程,及其 pid。 jps 也是一样,它的作用是显示当前系统的java进程情况,及其pid号。我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例),和他们的进程号(为下面几个程序做准备),并可通过opt来查看这些进程的详细启动参数。
1.1 语法
jps [-q] [-mlvV] [<hostid>]
1.1常用jps命令
命令 | 含义 |
---|---|
jps -l | 输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名 |
jps -q | 只显示 java 进程 pid |
jps -v | 输出给 jvm 传递的参数 |
jps -m | 输出传递给 main 方法的参数 |
jps --help | 输出帮助提示 |
jvm -v
二.jstack
jstack是java虚拟机自带的一种堆栈跟踪工具。
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
2.1 语法
jstack [-l] [-e] <pid>
基本参数
- -l: 长列表 ,打印有关锁的信息
- -e: 更多内容,打印有关线程的其他信息
- -h:打印此帮助信息
2.2常用操作
输出dump 内容至/home/jvm.dump
jstack -l -e [pid] > /home/jvm.dump
2.3 案例
java应用持续占用很高的cpu,如何排查?
- 使用top 命令 找出那个线程占用的
top
2. 使用 top -Hp [pid] ,找出线程pid
top -Hp 15703
然后将15968 转换成16 进制 3e60。
- 使用就stack命令 找出占用cpu 较高的代码
jstack -l -e 15703 |grep -A 20 '3e60'
三 jstat
Jstat用于监控基于HotSpot的JVM,对其堆的使用情况进行实时的命令行的统计,使用jstat我们可以对指定的JVM做如下监控:
-
类的加载及卸载情况
-
查看新生代、老生代及持久代的容量及使用情况
-
查看新生代、老生代及持久代的垃圾收集情况,包括垃圾回收的次数及垃圾回收所占用的时间
-
查看新生代中Eden区及Survior区中容量及分配情况等
3.1 语法
jstat -<option> [-t] [-h <n>] <pid> [<interval>] [<count>]
可以通过如下命令,知道option 支持的维度
jstat -options
3.1 options 统计维度表
Option | Displays |
---|---|
class | 用于查看类加载情况的统计 |
compiler | 用于查看HotSpot中即时编译器编译情况的统计 |
gc | 用于查看JVM中堆的垃圾收集情况的统计 |
gccapacity | 用于查看新生代、老生代及持久代的存储容量情况 |
gccause | 用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。 |
gcmetacapacity | 用于查看元空间的存储容量情况 |
gcnew | 用于查看新生代垃圾收集的情况 |
gcnewcapacity | 用于查看新生代的存储容量情况 |
gcold | 用于查看老生代及持久代发生GC的情况 |
gcoldcapacity | 用于查看老生代的容量 |
gcutil | 用于查看新生代、老生代及持代垃圾收集的情况 |
printcompilation | HotSpot编译方法的统计 |
3.2 参数
- -h n :用于指定每个几行就输出列头,如果不指定,指在第一行显示
- -t :用于在输出内容的第一列显示时间戳,此时间戳代表jvm
- vmid :VM的进程号,即当前运行的Java进程号
- interval:间隔时间,单位可以是秒或者毫秒,通过指定s或ms 确定,默认为ms
- count: 打印次数,缺省则打印无数次
3.3 统计维度及说明
3.3.1 -class
类加载情况的统计
列名 | 说明 |
---|---|
Loaded | 已经加载的类的数量 |
Bytes | 加载了的类的大小,单为Kb |
Unloaded | 卸载了的类的数量 |
Bytes | 卸载了的类的大小,单为Kb |
Time | 花在类的加载及卸载的时间 |
3.3.2 -compiler
HotSpot中即时编译器编译情况的统计
列名 | 说明 |
---|---|
Compiled | 编译任务执行的次数 |
Failed | 编译任务执行失败的次数 |
Invalid | 编译任务非法执行的次数 |
Time | 执行编译花费的时间 |
FailedType | 最后一次编译失败的编译类型 |
FailedMethod | 最后一次编译失败的类名及方法名 |
3.3.3 -gc
JVM中堆的垃圾收集情况的统计
列名 | 说明 |
---|---|
S0C | 新生代中Survivor space中S0当前容量的大小(KB) |
S1C | 新生代中Survivor space中S1当前容量的大小(KB) |
S0U | 新生代中Survivor space中S0容量使用的大小(KB) |
S1U | 新生代中Survivor space中S1容量使用的大小(KB) |
EC | Eden space当前容量的大小(KB) |
EU | Eden space容量使用的大小(KB) |
OC | Old space当前容量的大小(KB) |
OU | Old space使用容量的大小(KB) |
MC | Meta space当前容量的大小(KB) |
MU | Meta space使用容量的大小(KB) |
CCSC | 压缩类空间大小 (Compressed class space capacity (kB).) |
CCSU | 压缩类空间使用大小(Compressed class space used (kB).) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
YGCT | 从应用程序启动到采样时 Young GC 所用的时间(秒) |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时 Full GC 所用的时间(秒) |
CGC | 并发的垃圾收集次数 |
CGCT | 并发的垃圾收集总时间 |
GCT | 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC |
3.3.4 -gccapacity
新生代、老生代及持久代的存储容量情况
列名 | 说明 |
---|---|
NGCMN | 新生代的最小容量大小(KB) |
NGCMX | 新生代的最大容量大小(KB) |
NGC | 当前新生代的容量大小(KB) |
S0C | 当前新生代中survivor space 0的容量大小(KB) |
S1C | 当前新生代中survivor space 1的容量大小(KB) |
EC | Eden space当前容量的大小(KB) |
OGCMN | 老生代的最小容量大小(KB) |
OGCMX | 老生代的最大容量大小(KB) |
OGC | 当前老生代的容量大小(KB) |
OC | 当前老生代的空间容量大小(KB) |
MCMN | 元空间的最小容量大小(KB) |
MCMX | 元空间的最大容量大小(KB) |
MC | 当前元空间的空间容量大小 |
CCMSN | 最小压缩类空间大小 |
CCSMX | 最大压缩类空间大小 |
CCSC | 当前压缩类空间大小 |
PGC | 当前持久代的容量大小(KB) |
PC | 当前持久代的空间容量大小(KB) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
3.3.5 -gccause
这个选项用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因,它比-gcutil会多出最后一次垃圾收集原因以及当前正在发生的垃圾收集的原因。
用于查看垃圾收集的统计情况,包括最近发生垃圾的原因
列名 | 说明 |
---|---|
S0 | 幸存1区当前使用比例 |
S1 | 幸存2区当前使用比例 |
E | 新生代使用比例 |
O | 老年代使用比例 |
M | 元空间使用比例 |
CCS | 压缩使用比例 |
YGC | 新生代代垃圾回收次数 |
YGCT | 新生代垃圾回收总时间 |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时发生 Full GC 的总时间 |
CGC | 并发的垃圾收集次数 |
CGCT | 并发的垃圾收集总时间 |
LGCC | 最后一次垃圾收集的原因,可能为“unknown GCCause”、“System.gc()”等 |
GCT | gc cause 的垃圾收集总时间 |
3.3.6 -gcnew
新生代垃圾收集的情况
列名 | 说明 |
---|---|
S0C | 当前新生代中survivor space 0的容量大小(KB) |
S1C | 当前新生代中survivor space 1的容量大小(KB) |
S0U | S0已经使用的大小(KB) |
S1U | S1已经使用的大小(KB) |
TT | Tenuring threshold,要了解这个参数,我们需要了解一点Java内存对象的结构,在Sun JVM中,(除了数组之外的)对象都有两个机器字(words)的头部。第一个字中包含这个对象的标示哈希码以及其他一些类似锁状态和等标识信息,第二个字中包含一个指向对象的类的引用,其中第二个字节就会被垃圾收集算法使用到。在新生代中做垃圾收集的时候,每次复制一个对象后,将增加这个对象的收集计数,当一个对象在新生代中被复制了一定次数后,该算法即判定该对象是长周期的对象,把他移动到老生代,这个阈值叫着tenuring threshold。这个阈值用于表示某个/些在执行批定次数youngGC后还活着的对象,即使此时新生的的Survior没有满,也同样被认为是长周期对象,将会被移到老生代中。 |
MTT | Maximum tenuring threshold,用于表示TT的最大值 |
DSS | Desired survivor size (KB).可以参与这里:http://blog.csdn.net/yangjun2/article/details/6542357 |
EC | Eden space当前容量的大小(KB) |
EU | Eden space已经使用的大小(KB) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
YGCT | 从应用程序启动到采样时 Young GC 所用的时间(单位秒) |
3.3.7 -gcnewcapacity
新生代的存储容量情况
列名 | 说明 |
---|---|
NGCMN | 新生代的最小容量大小(KB) |
NGCMX | 新生代的最大容量大小(KB) |
NGC | 当前新生代的容量大小(KB) |
S0CMX | 当前新生代中S0的最大容量大小(KB) |
S0C | 当前新生代中SO的容量大小(KB) |
S1CMX | 当前新生代中S1的最大容量大小(KB) |
S1C | 当前新生代中S1的容量大小(KB) |
EC | 当前新生代中Eden的最大容量大小(KB) |
EC | 当前新生代中Eden的容量大小(KB) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
CGC | 并发的垃圾收集次数 |
3.3.8 -gcold
老生代及持久代发生GC的情况
列名 | 说明 |
---|---|
MC | 当前元空间容量的大小(KB) |
MU | 元空间使用容量的大小(KB) |
CCSC | 压缩类空间大小 |
CCSU | 压缩类空间使用大小 |
OC | 当前老年代容量的大小(KB) |
OU | 老年代使用容量的大小(KB) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时 Full GC 所用的时间(单位秒) |
CGC | 并发的垃圾收集次数 |
CGCT | 并发的垃圾收集总时间 |
GCT | 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC |
3.3.9 -gcoldcapacity
老生代的存储容量情况
列名 | 说明 |
---|---|
OGCMN | 老生代的最小容量大小(KB) |
OGCMX | 老生代的最大容量大小(KB) |
OGC | 当前老生代的容量大小(KB) |
OC | 当前新生代的空间容量大小(KB) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时 Full GC 所用的时间(单位秒) |
CGC | 并发的垃圾收集次数 |
CGCT | 并发的垃圾收集总时间 |
GCT | 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC |
3.3.10 -gcmetacapacity : 从应用程序启动到采样时发生 Full GC 的次数
元空间的存储容量情况
列名 | 说明 |
---|---|
MCMN | 元空间的最小容量大小(KB) |
MCMX | 元空间的最大容量大小(KB) |
MC | 当前元空间的容量大小(KB) |
CCSMN | 最小压缩类空间大小 |
CCSMX | 最大压缩类空间大小 |
CCSC | 当前压缩类空间大小 |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时 Full GC 所用的时间(单位秒) |
CGC | 并发的垃圾收集次数 |
CGCT | 并发的垃圾收集总时间 |
GCT | 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC |
3.3.11 -gcutil
新生代、老生代及持代垃圾收集的情况
列名 | 说明 |
---|---|
S0 | Heap上的 Survivor space 0 区已使用空间的百分比 |
S1 | Heap上的 Survivor space 1 区已使用空间的百分比 |
E | Heap上的 Eden space 区已使用空间的百分比 |
O | Heap上的 Old space 区已使用空间的百分比 |
M | 元空间space 区已使用空间的百分比 |
CCS | 压缩使用比例 |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
YGCT | 从应用程序启动到采样时 Young GC 所用的时间(单位秒) |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时 Full GC 所用的时间(单位秒) |
CGC | 并发的垃圾收集次数 |
CGCT | 并发的垃圾收集总时间 |
GCT | 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC |
3.3.12 -printcompilation
HotSpot编译方法的统计
列名 | 说明 |
---|---|
Compiled | 编译任务执行的次数 |
Size | 方法的字节码所占的字节数 |
Type | 编译类型 |
Method | 指定确定被编译方法的类名及方法名,类名中使名“/”而不是“.”做为命名分隔符,方法名是被指定的类中的方法,这两个字段的格式是由HotSpot中的“-XX:+PrintComplation”选项确定的。 |
四.jmap
打印出某个java进程(使用pid)内存中的所有‘对象’的情况(如:产生那些对象,及其数量)。
可以输出所有内存中对象的工具。
查看该进程(pid)下堆内存的使用情况:
jmap -heap pid
快速定位内存泄漏的方法:只统计存活的对象
jmap -histo:live pid
还可以导出:
jmap -histo:live [pid] >jmap.txt将信息输出到指定文件中
4.1 语法
jmap [-clstats ] [-finalizerinfo] [-histo[:live]] [-dump:<dump-option>] <pid>
4.2 参数
参数 | 含义 | 示例 |
---|---|---|
clstats | 打印Java类装载器统计信息 | jmap -clstats pid |
finalizerinfo | 打印等待回收的对象信息 | jmap -finalizerinfo pid |
histo | 打印 Java 对象堆的直方图。如果指定了 live 子选项,则它仅对活动对象进行计数 | jmap -histo:live pid |
dump | 链接运行的进程并转储 Java 堆 | jmap -dump:live,format=b,file=head.bin pid |
4.2.1 -clstats
- Index class的编号,
- Super - 父类的编号,
- InstBytes - 每个instance的bytes大小
- KlassBytes - 该class的bytes大小
- annotations - 注解大小
- CpAll - 每个class中constants, tags, cache, 和 operands的大小
- MethodCount - class中方法的个数
- Bytecodes - byte codes的大小
- MethodAll - method, CONSTMETHOD, stack map, 和 method data的大小
- ROAll - 可以放到read-only memory中的class元数据的大小
- RWAll - 可以放到read/write memory中的class元数据大小
- Total - ROAll + RWAll
- ClassName - 类名
4.2.2 -histo
instance 实例数 ,bytes 所占字节数 ,class name 类名
4.2.1 -dump
dump 出来的文件需要和其他工具配合才能查看
五.jinfo
jinfo用于打印指定Java进程、核心文件或远程调试服务器的Java配置信息。配置信息包括Java系统属性、Java虚拟机命令行标识参数。
5.1语法
jinfo [-flag <name>] [flag +|-<name>] [-flag <name>=value] [-flags] [-sysprops] <no option> <pid>
参数:
-flag | 打印这个VM Flags(name)参数的值 | jinfo -flag MaxHeapFreeRatio pid |
-flag +|- | 开启或者关闭对应名称的参数 只有被标记为 manageable 的参数才可以被动态修改 | jinfo -flag -HeapDumpAfterFullGC pid |
-flag= | 将这个VM Flags(name)设置为(value),只有被标记为 manageable 的参数才可以被动态修改 | jinfo -flag MaxHeapFreeRatio=60 pid |
-flags | 打印VM Flags | jinfo -flags pid |
-sysprops | 打印Java System properties | jinfo -syspropspid |
不填 | 打印VM Flags and system properties | jinfo pid |
# -version 是为了防止使用对应的命令弹出java help 输出。
#可查看所有JVM 参数最终值
java -XX:+PrintFlagsFinal -version
#可查看所有可以通过jinfo 实时修改的参数
java -XX:+PrintFlagsFinal -version|grep "manageable"
#可查看所有JVM参数启动值
java -XX:+PrintFlagsInitial -version
#查看哪些已经被用户或者 JVM 设置过的详细的 XX 参数的名称和值
java -XX:+PrintCommandLineFlags -version
六.jconsole
jconsole 是一个内置 Java 性能分析器,不需要安装,但由于它是一个GUI 图形化界面,所以必须有显示器显示。不然会出现如下图片所示报错。
不过我们可以通过windows 远程连接服务器,从而分析对应的性能情况。
启用远程,那么需要在远程服务器对应的java程序启动参数中增加如下参数,才可使用
//hostname 指的是启动服务的ip
-Djava.rmi.server.hostname=192.168.50.89
-Dcom.sun.management.jmxremote
// Linux机器上jmxremote 功能的端口号
-Dcom.sun.management.jmxremote.port=10092
//不开启ssl
-Dcom.sun.management.jmxremote.ssl=false
//参数代表远程连接时无需密码验证
-Dcom.sun.management.jmxremote.authenticate=false"
如下图所示
连接成功,剩余的就是通过此图形界面查看当前服务运行的状态