JVM性能、故障工具的使用
故障处理工具
jps
列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID
jps [options] [hostid]
参数说明
option | desc |
---|---|
-q | 只列出虚拟机进程id |
-m | 输出启动时传递给main()的参数 |
-l | 全类名,jar则显示路径 |
-v | 输出虚拟机启动时的JVM参数 |
jstat
监视虚拟机各种运行状态信息。类加载、内存、垃圾收集、即时编译等运行时数据。
jstat [option vmid [interval[s|ms] [count]]]
vmid 指的是jps查出来的虚拟机进程id
interval 是时间间隔
count 一共查多少次
举例:
监视jvm堆中的情况
jstat -gc vmid
列出表头
title | desc |
---|---|
S0C | survivor0 的大小 |
S1C | survivor1 的大小 |
S0C | survivor0 的使用情况 |
S1C | survivor1 的使用情况 |
EC | Eden 区的大小 |
EU | Eden 区的使用情况 |
OC | 老年代的大小 |
OU | 老年代的使用情况 |
MC | 方法区的大小 |
MU | 方法区的使用情况 |
CCSC | 压缩类空间的大小 |
CCSU | 压缩类空间的使用情况 |
YGC | 新生代垃圾回收次数 |
YGCT | 新生代垃圾回收消耗时间 |
FGC | 老年代垃圾回收次数 |
FGCT | 老年代垃圾回收消耗时间 |
GCT | 垃圾回收总时长 |
监视jvm堆中新生代的情况
jstat -gcnew vmid
TT
:对象在新生代存活的次数
MTT
:对象在新生代存活的最大次数
DSS
:期望Eden
区大小
监视jvm堆中老年代的情况
jstat -gcold vmid
jinfo
Java配置信息.实时查看和调整虚拟机各项参数.
jinfo [option] pid
这里的pid也是jps查出来的虚拟机进程id
jmap
生成对转储快照(heapdump|dump).
还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率、当前用的是哪种收集器等。
jmap [option] vmid
快照可以配合其他工具分析线上OOM等问题。
jhat
快照分析工具.
如上使用jmap大了快照之后,使用jhat后访问本地7000端口。
jstack
用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂
起等,都是导致线程长时间停顿的常见原因。
C:\Users\Administrator>jstack -help
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
写一个死锁体会一下jstack
public static void main(String[] args) {
Object lock1 = new Object();
Object lock2 = new Object();
new Thread(() -> {
synchronized (lock1){
try {
Thread.sleep(1000);
synchronized (lock2){
System.out.println("死锁");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
new Thread(() -> {
synchronized (lock2){
try {
Thread.sleep(1000);
synchronized (lock1){
System.out.println("死锁");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
}
两个线程相互持有对方请求的锁
排查
1 jps 查看vmid
2 stack -m vmid 定位死锁线程
C:\Users\Administrator>jps
12016 JeecgSystemCloudApplication
15744
2800 Jps
2888 ErpOmcContractManagerServiceImpl
C:\Users\Administrator>jstack -m 2888
Attaching to process ID 2888, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
Deadlock Detection:
Found one Java-level deadlock:
=============================
"Thread-0":
waiting to lock Monitor@0x0000022c7c599fa8 (Object@0x000000076d22ba18, a java/lang/Object),
which is held by "Thread-1"
"Thread-1":
waiting to lock Monitor@0x0000022c7c59c838 (Object@0x000000076d22ba08, a java/lang/Object),
which is held by "Thread-0"
Found a total of 1 deadlock.
----------------- 0 -----------------
0x00007ffff401c144 ntdll!NtWaitForSingleObject + 0x14
----------------- 1 -----------------
...
可视化故障处理根据
jconsole
见图知意
VisualVM