最近遇到了jvm调优的事情,用到了一些工具(jvisualvm、jconsole),墙裂推荐JProfiler(非免费)。也用到了一些jvm监控命令,遂想总结一下,以备后用。期间参考了不少资料,比如:
https://blog.csdn.net/wisgood/article/details/25343845
一、jps
(Java Virtual Machine Process Status Tool)
jps主要用来输出JVM中运行的进程状态信息。语法格式如下:
jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
C:\>jps -l -m
59476 sun.tools.jps.Jps -l -m
56844 org.apache.catalina.startup.Bootstrap start
二、jstat
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
(1)、类加载统计:
C:\>jstat -class 56844
Loaded Bytes Unloaded Bytes Time
3147 6133.6 0 0.0 12.75
(2)、编译统计
C:\>jstat -compiler 56844
Compiled Failed Invalid Time FailedType FailedMethod
1698 0 0 10.05 0
(3)、垃圾回收统计
C:\>jstat -gc 56844
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
64.0 64.0 0.0 0.0 65408.0 22430.3 65536.0 13735.8 17792.0 17259.3 2176.0 1978.4 1 0.130 0 0.000 0.130
(4)、堆内存统计
C:\>jstat -gccapacity 56844
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX
MC CCSMN CCSMX CCSC YGC FGC
65536.0 65536.0 65536.0 64.0 64.0 65408.0 65536.0 65536.0 65536.0 65536.0 0.0 1064960.0 17792.0 0.0 1048576.0 2176.0 1 0
(5)、新生代垃圾回收统计
C:\>jstat -gcnew 56844
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
64.0 64.0 0.0 0.0 0 0 32.0 65408.0 22430.3 1 0.130
(6)、新生代内存统计
C:\>jstat -gcnewcapacity 56844
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
65536.0 65536.0 65536.0 64.0 64.0 64.0 64.0 65408.0 65408.0 1 0
(7)、老年代垃圾回收统计
C:\>jstat -gcold 56844
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
17792.0 17259.3 2176.0 1978.4 65536.0 13735.8 1 0 0.000 0.130
(8)、老年代内存统计
C:\>jstat -gcoldcapacity 56844
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
65536.0 65536.0 65536.0 65536.0 1 0 0.000 0.130
(9)、元数据空间统计
C:\>jstat -gcmetacapacity 56844
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1064960.0 17792.0 0.0 1048576.0 2176.0 1 0 0.000 0.130
(10)、总结垃圾回收统计
C:\>jstat -gcutil 56844
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 34.29 20.96 97.01 90.92 1 0.130 0 0.000 0.130
(11)、JVM编译方法统计
C:\>jstat -printcompilation 56844
Compiled Size Type Method
1713 19 1 java/util/concurrent/CopyOnWriteArrayList iterator
三、jmap
(Memory Map)
JVM Memory Map命令用于生成heap dump文件,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候自动生成dump文件。 jmap不仅能生成dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。
命令格式:
参数
option:选项参数,不可同时使用多个选项参数
pid:java进程id,命令ps -ef | grep java获取
executable:产生核心dump的java可执行文件
core:需要打印配置信息的核心文件
remote-hostname-or-ip:远程调试的主机名或ip
server-id:可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器
options参数:
示例:
C:\>jmap -dump:live,format=b,file=d:/dump.hprof 56844
Dumping heap to D:\dump.hprof ...
Heap dump file created
dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名
四、jhat
(Java Heap Analysis Tool)
C:\>jhat -port 9998 d:/dump.hprof
Reading from d:/dump.hprof...
Dump file created Fri Sep 28 15:30:55 CST 2018
Snapshot read, resolving...
Resolving 134437 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 9998
Server is ready.
然后就可以访问http://localhost:9998查看了。
五、jstack
jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
命令行参数选项说明如下:
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
1,根据top命令,发现PID为7247的Java进程占用CPU高达300%,出现故障。
2,找到该进程后,如何定位具体线程或代码呢,首先显示线程列表,并按照CPU占用高的线程排序:
[root@localhost /]# ps -mp 7247 -o THREAD,tid,time | sort -rn
显示结果如下:
找到了耗时最高的线程7248,占用CPU时间一个半小时了!
将需要的线程ID转换为16进制格式:
[root@localhost /]# printf "%x\n" 7248
最后打印线程的堆栈信息:
[root@localhost /]# jstack 7247 |grep 1c50 -A 30
再查看ServiceTask.java的第54行,解决了。