本文简单介绍了jvm性能监控工具(jps、jstat、jinfo、jmap、jhat、jstack、jvisualvm和jconsole)以及示例,旨在说明常用的有哪些,具体每个监控工具的具体使用需要单独的去深入了解。

一般而言,基本上能满足日常的性能监控需要。

接下来,会介绍其他角度的监控需求和工具。

一、jvm性能监控工具介绍

JDK本身提供了很多方便的JVM性能调优监控工具,除了jps、jstat、jinfo、jmap、jhat、jstack等小巧的工具,还有集成式的jvisualvm和jconsole。 这些工具在 $JAVA_HOME/bin目录下。

二、jvm性能监控工具使用示例

1、jps

jps(JVM Process Status Tool,虚拟机进程监控工具),这个命令可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称,以及这些进程的本地虚拟机唯一ID。这个ID被称为本地虚拟机唯一ID(local virtual Machine Identifier,简写为LVMID)。如果你在linux的一台服务器上使用jps得到的LVMID其实就是和ps 命令得到的PID是一样的。

1)、语法格式

jps [options] [hostid]
# options参数选项说明如下:
# -q 不输出类名、Jar名和传入main方法的参数
# -m 输出传入main方法的参数
# -l 输出main类或Jar的全限名
# -v 输出传入JVM的参数

[root@bd-node-01 ~]$ jps -h
illegal argument: -h
usage: jps [-help]
       jps [-q] [-mlvV] [<hostid>]

Definitions:
    <hostid>:      <hostname>[:<port>]

如果不指定hostid就默认为当前主机或服务器

2)、使用示例

# 查看所有java进程
[root@server1 ~]# jps -lv
6366 sun.tools.jps.Jps -Dapplication.home=/usr/java/jdk1.8.0_144 -Xms8m
14143 org.apache.zookeeper.server.quorum.QuorumPeerMain -Dzookeeper.log.dir=/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../logs -Dzookeeper.log.file=zookeeper-alanchan-server-server1.log -Dzookeeper.root.logger=INFO,CONSOLE -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=kill -9 %p -Xmx1000m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false

2、jinfo

jinfo (Configuration Info for Java,配置信息工具) 这个命令可以实时地查看和调整虚拟机各项参数。

1)、语法格式

[root@server1 ~]# jinfo
Usage:
    jinfo [option] <pid>
        (to connect to running process)
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message

2)、使用示例

# 查看pid是14143信息
[root@server1 ~]# jinfo -flags 14143
Attaching to process ID 14143, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01
Non-default VM flags: -XX:CICompilerCount=4 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=526385152 -XX:+ManagementServer -XX:MaxHeapSize=1048576000 -XX:MaxNewSize=349175808 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=175112192 -XX:OldSize=351272960 -XX:OnOutOfMemoryError=null -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -Dzookeeper.log.dir=/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../logs -Dzookeeper.log.file=zookeeper-alanchan-server-server1.log -Dzookeeper.root.logger=INFO,CONSOLE -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=kill -9 %p -Xmx1000m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false

# 查看14143系统属性-sysprops 
jinfo -sysprops 14143

[root@server1 ~]# jinfo -sysprops 14143
Attaching to process ID 14143, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.144-b01
sun.boot.library.path = /usr/java/jdk1.8.0_144/jre/lib/amd64
jdk.tls.rejectClientInitiatedRenegotiation = true
zookeeper.root.logger = INFO,CONSOLE
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
com.sun.management.jmxremote.local.only = false
path.separator = :
java.rmi.server.randomIDs = true
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = CN
user.dir = /usr/local/bigdata/apache-zookeeper-3.7.1/bin
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_144-b01
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /usr/java/jdk1.8.0_144/jre/lib/endorsed
zookeeper.log.dir = /usr/local/bigdata/apache-zookeeper-3.7.1/bin/../logs
line.separator = 

java.io.tmpdir = /tmp
java.vm.specification.vendor = Oracle Corporation
os.name = Linux
sun.jnu.encoding = UTF-8
jetty.git.hash = 526006ecfa3af7f1a27ef3a288e2bef7ea9dd7e8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 2.6.32-754.35.1.el6.x86_64
user.home = /home/alanchan
user.timezone = GMT
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = alanchan
java.class.path = /usr/local/bigdata/apache-zookeeper-3.7.1/bin/../zookeeper-server/target/classes:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../build/classes:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../zookeeper-server/target/lib/*.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../build/lib/*.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/zookeeper-prometheus-metrics-3.7.1.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/zookeeper-jute-3.7.1.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/zookeeper-3.7.1.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/snappy-java-1.1.7.7.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/slf4j-reload4j-1.7.35.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/slf4j-api-1.7.35.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/simpleclient_servlet-0.9.0.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/simpleclient_hotspot-0.9.0.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/simpleclient_common-0.9.0.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/simpleclient-0.9.0.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/reload4j-1.2.19.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-transport-native-unix-common-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-transport-native-epoll-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-transport-classes-epoll-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-transport-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-resolver-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-handler-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-common-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-codec-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/netty-buffer-4.1.76.Final.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/metrics-core-4.1.12.1.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jline-2.14.6.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-util-ajax-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-util-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-servlet-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-server-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-security-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-io-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jetty-http-9.4.43.v20210629.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/javax.servlet-api-3.1.0.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jackson-databind-2.13.2.1.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jackson-core-2.13.2.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/jackson-annotations-2.13.2.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/commons-cli-1.4.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../lib/audience-annotations-0.12.0.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../zookeeper-*.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../zookeeper-server/src/main/resources/lib/*.jar:/usr/local/bigdata/apache-zookeeper-3.7.1/bin/../conf:
com.sun.management.jmxremote = 
zookeeper.4lw.commands.whitelist = *
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = org.apache.zookeeper.server.quorum.QuorumPeerMain /usr/local/bigdata/apache-zookeeper-3.7.1/bin/../conf/zoo.cfg
java.home = /usr/java/jdk1.8.0_144/jre
user.language = zh
zookeeper.server.3 = server3:2888:3888
java.specification.vendor = Oracle Corporation
zookeeper.server.2 = server2:2888:3888
zookeeper.server.1 = server1:2888:3888
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0_144
java.ext.dirs = /usr/java/jdk1.8.0_144/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /usr/java/jdk1.8.0_144/jre/lib/resources.jar:/usr/java/jdk1.8.0_144/jre/lib/rt.jar:/usr/java/jdk1.8.0_144/jre/lib/sunrsasign.jar:/usr/java/jdk1.8.0_144/jre/lib/jsse.jar:/usr/java/jdk1.8.0_144/jre/lib/jce.jar:/usr/java/jdk1.8.0_144/jre/lib/charsets.jar:/usr/java/jdk1.8.0_144/jre/lib/jfr.jar:/usr/java/jdk1.8.0_144/jre/classes
java.vendor = Oracle Corporation
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
zookeeper.log.file = zookeeper-alanchan-server-server1.log
sun.cpu.isalist =

3、jhat

jhat(虚拟机堆转储快照分析工具),这个工具是用来分析jmap dump出来的文件。 由于这个工具功能比较简陋,运行起来也比较耗时,所以这个工具不推荐使用,推荐使用MAT。 例如分析dump出来的test.bin,命令如下: jhat test.bin

它会在本地启动一个web服务,端口是7000,这样直接访问 127.0.0.1:7000就能看到分析结果了。

4、jmap

jmap(Memory Map for Java,内存映像工具),用于生成堆转存的快照,一般是heapdump或者dump文件。如果不适用jmap命令,可以使用-XX:+HeapDumpOnOutOfMemoryError参数,当虚拟机发生内存溢出的时候可以产生快照。或者使用kill -3 pid也可以产生。jmap的作用并不仅仅是为了获取dump文件,它可以查询finalize执行队列,java堆和永久代的详细信息,如空间使用率,当前用的哪种收集器。

1)、语法格式

jmap [option] vmid

[root@server1 ~]# jmap
Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system

# option参数说明:
# -dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
# -finalizerinfo 打印正等候回收的对象的信息.
# -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
# -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
# -permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
# -F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
# -h | -help 打印辅助信息
# -J 传递参数给jmap启动的jvm.

# 64位机上使用需要使用如下方式:
# jmap -J-d64 -heap pid

[root@server4 ~]# jps
20609 Jps
14291 RunJar
17174 Bootstrap
20407 launcher.jar
14553 RunJar
[root@server4 ~]# jmap -J-d64 -heap 17174
Attaching to process ID 17174, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 8417968128 (8028.0MB)
   NewSize                  = 175112192 (167.0MB)
   MaxNewSize               = 2805989376 (2676.0MB)
   OldSize                  = 351272960 (335.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 983040000 (937.5MB)
   used     = 381829904 (364.14137268066406MB)
   free     = 601210096 (573.3586273193359MB)
   38.841746419270834% used
From Space:
   capacity = 3670016 (3.5MB)
   used     = 3598368 (3.431671142578125MB)
   free     = 71648 (0.068328857421875MB)
   98.04774693080357% used
To Space:
   capacity = 38273024 (36.5MB)
   used     = 0 (0.0MB)
   free     = 38273024 (36.5MB)
   0.0% used
PS Old Generation
   capacity = 363331584 (346.5MB)
   used     = 72448600 (69.09236907958984MB)
   free     = 290882984 (277.40763092041016MB)
   19.940077656447286% used

43669 interned Strings occupying 5157360 bytes.

2)、示例

//1、打印每个class的实例数目,内存占用,类全名信息
jmap -histo 577
jmap -J-d64 -histo 17174
[root@server4 ~]# jmap -J-d64 -histo 17174

 num     #instances         #bytes  class name
----------------------------------------------
   1:        483580      102238480  [B
   2:       1006327       76303392  [C
   3:       1839385       73575400  java.util.TreeMap$Entry
   4:         77069       29724528  [I
   5:        746630       17919120  java.lang.String
   6:       1047408       16758528  java.lang.Integer
   7:        225725       11034328  [Ljava.lang.Object;
   8:        158836        6705424  [Ljava.lang.String;
   9:         63443        5582984  java.lang.reflect.Method
  10:        155578        4978496  java.util.HashMap$Node
  11:        152420        4877440  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
  12:        144704        4630528  net.sf.ehcache.store.disk.Segment$HashIterator
  13:         30315        4365360  com.mysql.jdbc.Field
  14:         90906        4363488  java.util.HashMap
  15:         43259        3995520  [Ljava.util.HashMap$Node;
  16:         41562        3360648  [S
  17:        104260        3336320  java.lang.StackTraceElement
  18:         83281        3331240  java.util.HashMap$KeyIterator
......
//2、dump heap内容到文件
jmap -J-d64 -dump:format=b,file=/usr/local/bigdata/testdata/jmap.bin 17174

[root@server4 ~]# jmap -J-d64 -dump:format=b,file=/usr/local/bigdata/testdata/jmap.bin 17174
Dumping heap to /usr/local/bigdata/testdata/jmap.bin ...
Heap dump file created

[root@server4 testdata]# ll
......
-rw------- 1 root root 682201881 6月  15 14:27 jmap.bin
......

5、jstat

jstat(JVM Statistics Monitoring Tool,虚拟机统计信息监视工具),这个命令用于监视虚拟机各种运行状态信息。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,虽然没有GUI图形界面,只是提供了纯文本控制台环境的服务器上,但它是运行期间定位虚拟机性能问题的首选工具。

1)、语法格式

jstat [option vmid [interval [s | ms] [count ] ] ]

[root@server4 ~]# jstat
invalid argument count
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as 
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.

# vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID
# interval是采样时间间隔
# count是采样数目

截图来自周志明的《深入理解Java虚拟机 第二版》

在这里插入图片描述

2)、示例

// 需要每300毫秒查询一次进程17174 垃圾收集状况,一共查询5次,那命令如下:
jstat -gc 17174 300 5

[root@server4 ~]# jstat -gc 17174 300 5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
3584.0 37376.0 3514.0  0.0   960000.0 409278.8  354816.0   70750.6   79320.0 76653.6 8192.0 7770.0     30    0.583   3      0.291    0.874
3584.0 37376.0 3514.0  0.0   960000.0 409278.8  354816.0   70750.6   79320.0 76653.6 8192.0 7770.0     30    0.583   3      0.291    0.874
3584.0 37376.0 3514.0  0.0   960000.0 409278.8  354816.0   70750.6   79320.0 76653.6 8192.0 7770.0     30    0.583   3      0.291    0.874
3584.0 37376.0 3514.0  0.0   960000.0 409278.8  354816.0   70750.6   79320.0 76653.6 8192.0 7770.0     30    0.583   3      0.291    0.874
3584.0 37376.0 3514.0  0.0   960000.0 409278.8  354816.0   70750.6   79320.0 76653.6 8192.0 7770.0     30    0.583   3      0.291    0.874

6、jstack

jstack(Java Stack Trace,Java堆栈跟踪工具),这个命令用于查看虚拟机当前时刻的线程快照(一般是thread dump 或者 java core文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。生成线程快照的主要目的是定位线程出现长时间停顿的原因,入线程间死锁、死循环、请求外部资源导致的长时间等待都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情。

1)、语法格式

jstack [option] vmid

[root@server4 ~]# jstack
Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

2)、示例

//查看进程17174的堆栈信息
[root@server4 ~]# jstack 17174
2023-06-15 14:37:09
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):

"Attach Listener" #58 daemon prio=9 os_prio=0 tid=0x00007fb01c001000 nid=0x57fb waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DefaultQuartzScheduler_QuartzSchedulerThread" #57 prio=5 os_prio=0 tid=0x00007faf54195800 nid=0x43b6 in Object.wait() [0x00007fafd1697000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:296)
        - locked <0x00000005cc1b85e8> (a java.lang.Object)


"schedulerJobAllTask_Worker-1" #29 prio=5 os_prio=0 tid=0x00007fb079a0e000 nid=0x439a in Object.wait() [0x00007fafd3bfa000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:519)
        - locked <0x00000005cc18b4e8> (a org.quartz.simpl.SimpleThreadPool$WorkerThread)

"user%0043ache.data" #27 prio=5 os_prio=0 tid=0x00007fb07981e000 nid=0x433d waiting on condition [0x00007fafd3cfb000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000005cb637cb0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"role%0052esource%0050ermission%0043ache.data" #20 prio=5 os_prio=0 tid=0x00007fb0797e2000 nid=0x4336 waiting on condition [0x00007fb0204d3000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000005cb696578> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"__DEFAULT__" #19 daemon prio=5 os_prio=0 tid=0x00007fb0797da800 nid=0x4335 in Object.wait() [0x00007fb0205d4000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000005cb74f498> (a java.util.TaskQueue)
        at java.lang.Object.wait(Object.java:502)
        at java.util.TimerThread.mainLoop(Timer.java:526)
        - locked <0x00000005cb74f498> (a java.util.TaskQueue)
        at java.util.TimerThread.run(Timer.java:505)

"Druid-ConnectionPool-Destroy-1084131337" #18 daemon prio=5 os_prio=0 tid=0x00007fb079655000 nid=0x4334 waiting on condition [0x00007fb020cd5000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:2032)

"Druid-ConnectionPool-Create-1084131337" #17 daemon prio=5 os_prio=0 tid=0x00007fb0796cd800 nid=0x4333 waiting on condition [0x00007fb020dd6000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000005cae3fa00> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:1948)

"Abandoned connection cleanup thread" #16 daemon prio=5 os_prio=0 tid=0x00007fb0795cd800 nid=0x432e in Object.wait() [0x00007fb0210d7000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000005cad385c8> (a java.lang.ref.ReferenceQueue$Lock)
        at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:64)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-BlockPoller" #15 daemon prio=5 os_prio=0 tid=0x00007fb0786a3000 nid=0x432d runnable [0x00007fb048584000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
        at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
        at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000005ca443418> (a sun.nio.ch.Util$3)
        - locked <0x00000005ca443428> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000005ca4433d0> (a sun.nio.ch.EPollSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:313)

"GC Daemon" #14 daemon prio=2 os_prio=0 tid=0x00007fb07848d000 nid=0x432c in Object.wait() [0x00007fb048cdb000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000005ca4322b8> (a sun.misc.GC$LatencyLock)
        at sun.misc.GC$Daemon.run(GC.java:117)
        - locked <0x00000005ca4322b8> (a sun.misc.GC$LatencyLock)

"AsyncFileHandlerWriter-2093176254" #12 daemon prio=5 os_prio=0 tid=0x00007fb0781d8800 nid=0x432a waiting on condition [0x00007fb04937b000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000005ca44fc50> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.LinkedBlockingDeque.pollFirst(LinkedBlockingDeque.java:522)
        at java.util.concurrent.LinkedBlockingDeque.poll(LinkedBlockingDeque.java:684)
        at org.apache.juli.AsyncFileHandler$LoggerThread.run(AsyncFileHandler.java:159)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007fb0780d1800 nid=0x4328 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007fb0780c6800 nid=0x4327 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007fb0780c4800 nid=0x4326 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fb0780c2800 nid=0x4325 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fb0780c0000 nid=0x4324 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fb0780be800 nid=0x4323 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fb07808b800 nid=0x4322 in Object.wait() [0x00007fb049fde000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000005ca41aaf8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fb078087000 nid=0x4321 in Object.wait() [0x00007fb04a0df000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x00000005ca456058> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x00007fb078009000 nid=0x4317 runnable [0x00007fb07f917000]
   java.lang.Thread.State: RUNNABLE
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
        at java.net.ServerSocket.implAccept(ServerSocket.java:545)
        at java.net.ServerSocket.accept(ServerSocket.java:513)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:609)
        at org.apache.catalina.startup.Catalina.await(Catalina.java:864)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:810)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)

"VM Thread" os_prio=0 tid=0x00007fb07807f000 nid=0x4320 runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fb07801e800 nid=0x4318 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fb078020000 nid=0x4319 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fb078022000 nid=0x431a runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fb078023800 nid=0x431b runnable 

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007fb078025800 nid=0x431c runnable 

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007fb078027000 nid=0x431d runnable 

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007fb078029000 nid=0x431e runnable 

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007fb07802a800 nid=0x431f runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007fb0780d4800 nid=0x4329 waiting on condition 

JNI global references: 439

7、jconsole

jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。命令行里打 jconsole,选则进程就可以了。 使用步骤

1)、启动

cmd中输入命令 jconsole

在这里插入图片描述

正常启动的界面

在这里插入图片描述

2)、连接

在这里插入图片描述

3)、查看

  • 概览

在这里插入图片描述

  • 内存

在这里插入图片描述

  • 线程

在这里插入图片描述

在这里插入图片描述

  • vm概要

在这里插入图片描述

  • NBean

在这里插入图片描述

8、jvisualvm

jvisualvm同jconsole都是一个基于图形化界面的、可以查看本地及远程的JAVA GUI监控工具,Jvisualvm同jconsole的使用方式一样,直接在命令行打入jvisualvm即可启动,jvisualvm界面更美观一些,数据更实时。

1)、启动

cmd中输入jvisualvm

在这里插入图片描述

在这里插入图片描述

2)、连接

选择本地服务

在这里插入图片描述

3)、查看

  • 概述

在这里插入图片描述

  • 监视

在这里插入图片描述

  • 线程

在这里插入图片描述

  • 抽样器

在这里插入图片描述

以上,简单的介绍了8种jvm性能监控的工具。

来源:jvm性能监控工具(jps、jstat、jinfo、jmap、jhat、jstack、jvisualvm和jconsole)介绍及示例 - 知乎 (zhihu.com)