梦想还是要有的,万一忘了咋办?

0%

Java虚拟机性能监控工具

依赖数据

  • 运行日志
  • 异常堆栈
  • GC日志
  • 线程快照
  • 堆转储快照

获取数据

工具概述

工具存放位置

${JavaHome}/bin/

工具代码逻辑在

jdk/lib/tools.jar

Jdk1.5虚拟机时
   
   启动时增加 -Dcom.sun.management.jmxremote 启动jmx功能,否则部分工具无法使用

工具介绍

upload successful

jps

虚拟机进程状况恐惧,类似linux ps指令。用于获取当前运行的 java进程情况

jps命令格式:

jps [options] [hostid]

jps执行样例:

$ ~ jps -l
43629 sun.tools.jps.Jps
431

jps主要选项
upload successful

jstat

虚拟机统计信息监控工具jstat(Jvm Statistics Monitoring Tool),可以获取虚拟机进程中:

  • 类装载
  • 内存
  • 垃圾回收
  • JIT编译

jstat命令格式:

jstat [option vmid [interval[s|ms] [count] ]
   
远程vmid格式

[protocol:][//]lvmid[@hostname[:port]/servername]

其中

  • interval 间隔时间,默认 无
  • count 执行次数,默认1次

示例:

jstat -gc 2764 100 10
   
查询进程为2764的虚拟机 垃圾收集信息,每个100ms查询一次,一共查询10次。

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
~ jstat -gc 431  100 10
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525
14144.0 14144.0 0.0 0.0 113536.0 2372.7 283440.0 156408.7 378640.0 349994.2 48716.0 42774.9 411 5.382 28 80.143 85.525

其中

YGC      YGCT          FGC    FGCT     GCT

YGC次数   YGC总消耗时间  FGc次数 Fgc总时间 所有GC总时间
jstat命令选项:
jstat

jinfo

Java配置信息工具jinfo(Configuration Info for java)作用:

  • 实时查看、调整 虚拟机各项参数

jinfo命令格式:

jinfo [option] pid

Mac + Jdk1.8 无法使用测试jinfo命令。

jmap

jmap(Memory Map for Java)用于生成堆转储快照(一般为heapdump或dump文件)。不用jmap还可以通过以下方式获取dump文件:

  • -XX:+HeapDumpOnOutOfMemoryError
    当虚拟机遇到oom异常时就会自动生成dump文件。
  • -XX:+HeapDumpOnCtrlBreak
    可以使用ctrl+break键让虚拟机生成dump文件
  • linux 下通过kill -3 pid
    吓唬虚拟机生成dump文件。

jmap工具主要选项

jmap

dump文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007f837d042800 nid=0x3f03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007f837c005800 nid=0x2603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"T2" #11 prio=5 os_prio=31 tid=0x00007f837c8ed000 nid=0x3e03 waiting for monitor entry [0x0000700003f70000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.hardydou.jmm.DeadLock.doSomeThing(DeadLock.java:29)
- waiting to lock <0x000000079570f7d0> (a java.lang.String)
- locked <0x000000079570f800> (a java.lang.String)
at com.hardydou.jmm.DeadLock.run(DeadLock.java:37)

"T1" #10 prio=5 os_prio=31 tid=0x00007f837c858000 nid=0x3c03 waiting for monitor entry [0x0000700003e6d000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.hardydou.jmm.DeadLock.doSomeThing(DeadLock.java:29)
- waiting to lock <0x000000079570f800> (a java.lang.String)
- locked <0x000000079570f7d0> (a java.lang.String)
at com.hardydou.jmm.DeadLock.run(DeadLock.java:37)

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

"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007f837c076800 nid=0x3803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007f837b815000 nid=0x4603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007f837d03e800 nid=0x4703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007f837d01e800 nid=0x4903 runnable [0x000070000385b000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x00000007957af218> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x00000007957af218> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f837c827000 nid=0x360b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f837c842800 nid=0x2f03 in Object.wait() [0x0000700003655000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795588ec0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x0000000795588ec0> (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=31 tid=0x00007f837c016000 nid=0x5203 in Object.wait() [0x0000700003552000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795586b68> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000795586b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=31 tid=0x00007f837d00a000 nid=0x2e03 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007f837d004800 nid=0x1f07 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007f837d005800 nid=0x1e03 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007f837d006000 nid=0x2b03 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007f837d006800 nid=0x2d03 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007f837d042000 nid=0x4303 waiting on condition

JNI global references: 33


Found one Java-level deadlock:
=============================
"T2":
waiting to lock monitor 0x00007f837c01c0a8 (object 0x000000079570f7d0, a java.lang.String),
which is held by "T1"
"T1":
waiting to lock monitor 0x00007f837c0196b8 (object 0x000000079570f800, a java.lang.String),
which is held by "T2"

Java stack information for the threads listed above:
===================================================
"T2":
at com.hardydou.jmm.DeadLock.doSomeThing(DeadLock.java:29)
- waiting to lock <0x000000079570f7d0> (a java.lang.String)
- locked <0x000000079570f800> (a java.lang.String)
at com.hardydou.jmm.DeadLock.run(DeadLock.java:37)
"T1":
at com.hardydou.jmm.DeadLock.doSomeThing(DeadLock.java:29)
- waiting to lock <0x000000079570f800> (a java.lang.String)
- locked <0x000000079570f7d0> (a java.lang.String)
at com.hardydou.jmm.DeadLock.run(DeadLock.java:37)

Found 1 deadlock.

Heap
PSYoungGen total 38400K, used 7323K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
eden space 33280K, 22% used [0x0000000795580000,0x0000000795ca6e80,0x0000000797600000)
from space 5120K, 0% used [0x0000000797b00000,0x0000000797b00000,0x0000000798000000)
to space 5120K, 0% used [0x0000000797600000,0x0000000797600000,0x0000000797b00000)
ParOldGen total 87552K, used 0K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
object space 87552K, 0% used [0x0000000740000000,0x0000000740000000,0x0000000745580000)
Metaspace used 3818K, capacity 4540K, committed 4864K, reserved 1056768K
class space used 423K, capacity 428K, committed 512K, reserved 1048576K


Process finished with exit code 137 (interrupted by signal 9: SIGKILL)

jhat

jhat(JVM Heap Analysis Tool)虚拟机堆转储快照分析工具(分析dump文件),内嵌html服务器,可以通过浏览器查看分析结果。不建议使用。
结果以包为集合分组显示。主要看里面的 Heap Histogram 项目(与jmap -histo 功能一样)与OQL页签功能。

jstack

Java堆栈跟踪工具jstack(Stack Trace for Java),用于获取虚拟机当前时刻的线程快照(每一条线程正在执行的方法栈的集合)。目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待。

JDK1.5中,java.lang.Thread 新增一个getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象,有同样的效果。

jstack命令格式:

jstack [option] vmid

jstack命令主要选项:
upload successful

demo样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
2019-05-27 13:46:49
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007fed89037800 nid=0x3f03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007fed8985f000 nid=0x2703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"T2" #11 prio=5 os_prio=31 tid=0x00007fed8a0ed800 nid=0x3d03 waiting for monitor entry [0x000070000acde000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.hardydou.jmm.DeadLock.doSomeThing(DeadLock.java:29)
- waiting to lock <0x000000079570f8d8> (a java.lang.String)
- locked <0x000000079570f908> (a java.lang.String)
at com.hardydou.jmm.DeadLock.run(DeadLock.java:37)

Locked ownable synchronizers:
- None

"T1" #10 prio=5 os_prio=31 tid=0x00007fed8a0ed000 nid=0x4303 waiting for monitor entry [0x000070000abdb000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.hardydou.jmm.DeadLock.doSomeThing(DeadLock.java:29)
- waiting to lock <0x000000079570f908> (a java.lang.String)
- locked <0x000000079570f8d8> (a java.lang.String)
at com.hardydou.jmm.DeadLock.run(DeadLock.java:37)

Locked ownable synchronizers:
- None

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

Locked ownable synchronizers:
- None

"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007fed8a0a7000 nid=0x4603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007fed8a0a6000 nid=0x3803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007fed8985e800 nid=0x3603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:
- None

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007fed8981c800 nid=0x4903 runnable [0x000070000a5c9000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x00000007957af110> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x00000007957af110> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

Locked ownable synchronizers:
- None

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

Locked ownable synchronizers:
- None

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fed89807800 nid=0x5003 in Object.wait() [0x000070000a3c3000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795588ec0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x0000000795588ec0> (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)

Locked ownable synchronizers:
- None

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

Locked ownable synchronizers:
- None

"VM Thread" os_prio=31 tid=0x00007fed89807000 nid=0x2c03 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fed8a80d800 nid=0x2007 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fed8a80e000 nid=0x2303 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fed8a80e800 nid=0x2a03 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fed8a80f800 nid=0x5303 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007fed8a026800 nid=0x4403 waiting on condition

JNI global references: 33


Found one Java-level deadlock:


JConsole

可视化工具,包含:概述、内存、线程、类、vm摘要、MBean 等6个标签。

upload successful

upload successful

upload successful

upload successful