jvm---6、JVM 分析及监控工具

jdk 自带分析及监控工具
jps JVM Process Status Tool              显示所有的HotSpot 虚拟机进程
jstat         JVM Statistics Monitoring Tool     收集HotSpot 虚拟机各方面的运行数据
jinfo        Configuration Info for Java            显示虚拟机配置信息
jmap Memory Map of java                 生成虚拟机内存快照 heapdump 文件
jhat        JVM Heap dump Browser          用于分析 heapdump 文件,创建一个http/html 服务,在浏览器可以查看分析结果

jstack      stack Trace for Java                    显示虚拟机的线程快照


写在前面:
java 启动进程时会在 /tmp/hsperfdata_userName (userName 是用户名,启动java进程的用户)目录下创建以进程号为文件名的文件,描述的是此java 进程的信息。jps、jstat 等都是从这个文件中获取数据的。如果使用jps 查看不到java进程,而用 ps -ef|grep java 能查看到,可能就是这个文件当前用户没有权限。


jps 查看 java 进程信息
jps [-qmlv]  [java进程号,如果没有查看所有的java 进程]  
-q 只展示进程号
-m 查看进程启动时,传递到main函数的参数
-l 输出主类的命名,如果是jar ,就输出jar 的全路径
-v jvm启动时,输出jvm 参数
示例:
$ jps -mvl
61446 sun.tools.jps.Jps -mvl -Denv.class.path=/usr/jdk1.8.0/lib:/usr/jdk1.8.0/jre/lib -Dapplication.home=/usr/jdk1.8.0 -Xms8m


jstat 监视jvm 各种运行状态信息,如:类装载、内存、垃圾收集、JIT 编译等运行数据。
命令格式:
jstat [option  vmid [interval[s|ms]  [count] ]   ]  option代表查询虚拟机信息,  vmid java进程号, interval 时间间隔(默认是ms),   count是查询次数

示例: 查看 13735 进程gc信息, 200ms 一次查看 2次
$ jstat -gc 13735 200  2

option 选项值:
-class 监视类装载、制裁数量、总空间以及类装载所耗时间
-gc 监视堆状况,包括 Eden区,Survivor区,老年代,永久代等容量及已用空间,GC 时间合计
-gccapacity    与-gc基本相同,输出主要关注各个区的使用到的最大,最小空间
-gcutil 与-gc基本相同,输出主要关注已使用空间占总空间的百分比
-gccause 与-gcutil功能一样,额外会输出产生上一次gc的原因
-gcnew 监视新生代GC 状况
-gcnewcapatity 与-gcnew 基本相同,输出主要关注新生代使用到的最大、最小空间。
-gcold 监视老年代
-gcoldcapacity 监视老年代,输出主要关注的是老年代使用到的最大、最小空间
-gcpermcapacity 输出永久代用到的最大最小空间
-compiler 输出JIT 编译器编译过的方法、耗时等信息
-printcompilation    输出已经被JIT 编译的方法

示例:
1、查看 13735 进程gc信息, 200ms 一次查看 2次
$ jstat -gc 13735 200  2

S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 16384.0 0.0 16384.0 131072.0 65536.0 114688.0 0.0 19328.0 18794.0 2176.0 2051.8 9 5.475 0 0.000 5.475
0.0 16384.0 0.0 16384.0 131072.0 65536.0 114688.0 0.0 19328.0 18794.0 2176.0 2051.8 9 5.475 0 0.000 5.475
         输出分析:
S0C      S 是Servivor 区,0 表示Servivor的 0 区,C 是Capacity (容量)
S0C      和上面一致,  1 表 Servivor 的 1 区
S0U      S  和 0 的意思和上面一样,U 就是 Used(已使用)
EC       E 表示 Eden 区, C 就是Capacity
EU       Eden  Used
OC       Old 区 Capacity
OU       Old 区 Used
MC       M 就是method,就是 method area capacity
MU       method area used
CCSC      第一个C是class, CS是:compress ,最后一个C是:capacity,所以就是:class compress capacity   压缩类空间大小
CCSU 同上解释,压缩类空间使用大小
YGC young GC 次数
YGCT young GC 总耗间
FGC FullGC 次数
FGCT FullGC 总时间
GCT GC 总时间

2、 查看各区最大最小用量
$ jstat -gccapacity 13735 200  2

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
0.0 262144.0 147456.0 0.0 16384.0 131072.0 0.0 262144.0 114688.0 114688.0 0.0 1067008.0 19328.0 0.0 1048576.0 2176.0 9 0
0.0 262144.0 147456.0 0.0 16384.0 131072.0 0.0 262144.0 114688.0 114688.0 0.0 1067008.0 19328.0 0.0 1048576.0 2176.0 9 0
分析:
NGCMN   N 就是年轻代  GCMN GC最小容量
NGCMX   就是最大使用量了
NGC    当前新生代容量
规则:  O  old,  C class,M method,GC 就是GC ,MX 最大值,MN 最小值, 
后面的就是你猜的意思,就不列举了。

3、查看内存各区使用百分比
$ jstat -gcutil 13735 200  2
  S0     S1     E      O      M     CCS       YGC     YGCT    FGC    FGCT     GCT   
  0.00 100.00  62.50   0.00  97.24  94.29      9    5.475     0    0.000    5.475
  0.00 100.00  62.50   0.00  97.24  94.29      9    5.475     0    0.000    5.475
  看完上面的,这是就不用分析了。

4、查看GC 原因
$ jstat -gccause 13735 200  2
  S0     S1     E      O      M     CCS    YGC     YGCT      FGC    FGCT     GCT      LGCC              GCC                 
  0.00 100.00  62.50   0.00  97.24  94.29      9    5.475     0    0.000    5.475 G1 Evacuation Pause  No GC               
  0.00 100.00  62.50   0.00  97.24  94.29      9    5.475     0    0.000    5.475 G1 Evacuation Pause  No GC 
  分析:
LGCC    last gc cause  上一次GC 原因
GCC     gc cause 当前GC 原因

jinfo  实时查看和调整JVM 参数
查看帮助:
$ 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        查看参数 name  的值
-flag [+|-]<name>    to enable or disable the named VM flag 启用(+),禁用(-) 参数name 的设置
-flag <name>=<value> to set the named VM flag to the given value 设置参数name 的值
-flags               to print VM flags 打印所有参数设置,把显示设置,和使用系统默认的分开
-sysprops            to print Java system properties 打印出 System.getProperties() 的值
<no option>          to print both of the above
-h | -help           to print this help message



命令格式:
jinfo [option] pid

示例:
1、查看进程的所有参数
$ jinfo -flags 13735
Attaching to process ID 13735, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.111-b14
Non-default VM flags: -XX:+AlwaysPreTouch ....... 省略
Command line:  -Xms256m -Xmx256m -Xmn128m ......  省略

Non-default VM flags    系统默认参数
Command line: 显示设置

2、禁用 PrintGC
$ jinfo -flag -PrintGC  13735
$ jinfo -flag PrintGC 13735     查看PrintGC 已被禁用了
-XX:-PrintGC   
$ jinfo -flag +PrintGC  13735    重新启用

3、修改 NumberOfGCLogFiles 的值
$ jinfo -flag NumberOfGCLogFiles 13735        查看 NumberOfGCLogFiles 值
-XX:NumberOfGCLogFiles=5
$ jinfo -flag NumberOfGCLogFiles=10 13735 不能修改异常,就是示例。可以改别的

jmap  内存映像工具,用于生成堆转存快照(叫:headdump 或 dump 文件),还可以查询finalize 执行队列,java堆和永久代信息(空间使用率,当前用的是哪种收集器等)
命令格式:
jmap [option]  pid

-dump 生成Java堆转存快照。格式:-dump:[live,]format=b, file=<filename> , live 只dump出存活对象
-heap 显示Java堆详细信息。如:哪种回收器参数配置、分代状况。只在linux/Solaris平台有效
-histo 显示堆中对象统计信息,包括类、实例数量、合计数量
-permstat 以ClassLoader 为统计口径显示永久代状态。只在linux/Solaris平台有效  (1.8版本没有这个参数了)
-F 当JVM 进程对-dump 选项没有响应时,强制生成dump 文件。只在linux/Solaris平台有效
-fiinalizerinfo 显示在F-Queue 中等待Finalizer 线程执行的finalize 方法的对象。只在linux/Solaris平台有效

示例:
1、生成堆快照
$ jmap -dump:live,format=b,file=/tmp/dump_13735 13735
生成的文件:
-rw-------. 1 jamin jamin  13M Jun 11 06:31 dump_13735

dump 文件分析:jhat命令、IBM HeapAnalyzer 工具,Eclipse Memory Analyzer

2、查看jvm配置、内存使用、GC 详情
$ jmap -heap 13735
Attaching to process ID 13735, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.111-b14

using thread-local object allocation.
Garbage-First (G1) GC with 1 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 40 堆释放最小百分比,堆至少要占用40%,才触发GC 
   MaxHeapFreeRatio         = 70 堆释放最大百分比,堆占用了70%,必须要触发GC 
   MaxHeapSize              = 268435456 (256.0MB) 最大堆内存
   NewSize                  = 134217728 (128.0MB) 新生代大小
   MaxNewSize               = 134217728 (128.0MB) 新生代最大大小
   OldSize                  = 5452592 (5.1999969482421875MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 134217728 (128.0MB) Metaspace空间大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) 类压缩空间
   MaxMetaspaceSize         = 335544320 (320.0MB) 最大的 Metaspace 大小(后续介绍)
   G1HeapRegionSize         = 16777216 (16.0MB) G1收集器 region 大小


Heap Usage:
G1 Heap:
   regions  = 16
   capacity = 268435456 (256.0MB) 堆大小
   used     = 43959512 (41.923057556152344MB) 使用大小
   free     = 224475944 (214.07694244384766MB) 空闲大小
   16.37619435787201% used 使用百分比
G1 Young Generation:
Eden Space: Eden 空间
   regions  = 2
   capacity = 134217728 (128.0MB)
   used     = 33554432 (32.0MB)
   free     = 100663296 (96.0MB)
   25.0% used
Survivor Space:
   regions  = 1
   capacity = 16777216 (16.0MB)
   used     = 16777216 (16.0MB)
   free     = 0 (0.0MB)
   100.0% used
G1 Old Generation:
   regions  = 1
   capacity = 117440512 (112.0MB)
   used     = 0 (0.0MB)
   free     = 117440512 (112.0MB)

   0.0% used

8287 interned Strings occupying 746664 bytes.  8287 个字符串 interned ,占用 746664 bytes

3、类实例化信息
$ jmap -histo 13735
num     #instances         #bytes  class name
----------------------------------------------
   1:         25511        3912432  [C
   2:         14495        3690176  [B
   3:          6614        2467024  [Ljava.lang.Object;
   4:           605        1495560  [Lorg.apache.rocketmq.common.MQVersion$Version;
   ......
序号 实例化个数   实例总大小   类名

4、查看F-Queue 队列中的对象
$ jmap -finalizerinfo  13735
Attaching to process ID 13735, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.111-b14
Number of objects pending for finalization: 0
我实验jvm 没有

jhat  分析jvm堆快照文件
就是分析jmap 生成dump 文件,jmap 生成的dump 是二进制文件,不能直接查看。
jhat 分启动一个内置的http/html 服务,分析的结果比较简单,分析比较耗时。所以一般不直接使用。
后面再讲分析dump

jstack  用于生成虚拟机当前时刻线程快照(当前JVM 内每条线程正在执行的方法堆栈集合,叫:threaddump或javacore)。
定位线程出现长时间停顿的原因,使用jstack 就可以知道停顿的线程在做什么。
命令格式:
jstack -Flm pid
-F  当正常输出的请求不被响应时,强制输出线程堆栈
-l  除堆栈外,输出锁的信息。l  就是lock
-m 如果调用的是本地方法,可以显示 C/C++ 的堆栈。m 就是 method

示例:
$ jstack -l 13735
"NettyServerCodecThread_7" #24 prio=5 os_prio=0 tid=0x00007f2540114000 nid=0x42ba waiting on condition [0x00007f252f25a000]
#线程名,                     优先级   系统优先级   线程id                         等待condition
java.lang.Thread.State: TIMED_WAITING (parking)   线程状态
at sun.misc.Unsafe.park(Native Method)       是native 方法
- parking to wait for  <0x00000000f009cb00> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)   
此线程在等待线程的id
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.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:269)
at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:39)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:     拥有锁和同步块信息
- None

注:jstack 中会出现的线程状态
Deadlock 死锁
Runnable      运行
Waiting on condition 等待条件
Waiting on monitor entry      等待获取监视器
Suspended      暂停
Object.wait(),TIMED_WAITING 对象等待中
Blocked 阻塞  
Parked 停止,还没有销毁

后面会补一篇相关线程分析



猜你喜欢

转载自blog.csdn.net/convict_eva/article/details/80649974
今日推荐