编程技术文章分享与教程

网站首页 > 技术文章 正文

收藏!JVM故障和性能分析利器

hmc789 2024-11-19 04:56:27 技术文章 1 ℃

一、jcmd

jcmd的作用是发送诊断命令请求到正在运行的Java虚拟机(JVM),打印出java进程运行和性能相关的信息,它必须和JVM运行在同一台机器上,并且与启动JVM用户具有相同的组权限。

灵活使用jcmd可以快速获得运行的java进程相关的信息,例如性能数据、参数、heapdump、threaddump等,非常方便,堪称利器。用法如下:

  • jcmd -l :列出当前所有运行的 java 进程
  • jcmd pid help :列出当前运行的 java 进程可以执行的操作(command)
  • jcmd pid|main-class PerfCounter.print :打印性能相关信息
  • jcmd pid|main-class -f filename :读取文件中的命令并执行,#开头的行会被当作注视忽略
  • jcmd pid|main-class command [arguments] arguments可以通过jcmd pid help command查看

支持的参数如下:

命令

描述

VM.uptime

查看JVM的启动时长

GC.class_histogram

查看JVM的类信息,可以查看每个类的实例数量和占用空间大小

Thread.print

查看JVM的Thread Dump

GC.heap_dump filename

生成JVM的Heap Dump,指定生成的文件名

VM.system_properties

查看JVM的属性信息

VM.flags

查看JVM的启动参数,可以查看-X和-XX参数

VM.command_line

查看JVM的启动命令行

GC.run_finalization

对JVM执行java.lang.System.runFinalization,将会调用对象的finalize方法,尽量不要使用。

GC.run

对JVM执行java.lang.System.gc(),提醒垃圾收集器进行垃圾收集,但具体JVM有没有进行垃圾收集却无法确定。

PerfCounter.print

查看JVM性能信息

VM.native_memory

JVM的native memory大小

ManagementAgent.stop

停止Management Agent

ManagementAgent.start

启动Management Agent

ManagementAgent.start_local

启动本地Management Agent

VM.classloader_stats

打印Classloader详细信息

GC.rotate_log

GC日志

GC.class_stats

加载的类的详细信息

GC.finalizer_info

GC调用finalize方法的信息

GC.heap_info

GC堆的相关信息

VM.dynlibs

动态加载的jar包

VM.version

VM版本信息

本人最常用的是PerfCounter.print、GC.class_histogram、Thread.print和VM.flags,效果如下:

PerfCounter.print查看JVM性能相关信息:

jcmd 1755 PerfCounter.print
1755:
java.ci.totalTime=13601090874
java.cls.loadedClasses=14492
java.cls.sharedLoadedClasses=0
java.cls.sharedUnloadedClasses=0
java.cls.unloadedClasses=0
java.property.java.class.path="/opt/elasticsearch-6.3.0/lib/elasticsearch-6.3.0.jar:/opt/elasticsearch-6.3.0/lib/elasticsearch-x-content-6.3.0.jar:/opt/elasticsearch-6.3.0/lib/elasticsearch-cli-6.3.0.jar:/opt/elasticsearch-6.3.0/lib/elasticsearch-core-6.3.0.jar:/opt/elasticsearch-6.3.0/lib/lucene-core-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-analyzers-common-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-backward-codecs-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-grouping-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-highlighter-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-join-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-memory-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-misc-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-queries-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-queryparser-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-sandbox-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-spatial-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-spatial-extras-7.3.1.jar:/opt/elasticsearch-6.3.0/lib/lucene-spatial3d-7.3.1.jar:/opt/elastic"
java.property.java.endorsed.dirs="/opt/jdk1.8.0_191/jre/lib/endorsed"
java.property.java.ext.dirs="/opt/jdk1.8.0_191/jre/lib/ext:/usr/java/packages/lib/ext"
java.property.java.home="/opt/jdk1.8.0_191/jre"
java.property.java.library.path="/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib"
java.property.java.version="1.8.0_191"
java.property.java.vm.info="mixed mode"

查看GC情况:

jcmd 1755 GC.class_histogram
1755:

 num     #instances         #bytes  class name
----------------------------------------------
   1:          5432       18997040  [B
   2:        132477       11619136  [C
   3:        152697        4886304  java.util.HashMap$Node
   4:        122068        2929632  java.lang.String
   5:         43778        2101344  java.util.HashMap
   6:         19537        1977768  [Ljava.util.HashMap$Node;
   7:         15145        1660888  java.lang.Class
   8:         49096        1571072  java.util.concurrent.ConcurrentHashMap$Node
   9:         17505        1177936  [Ljava.lang.Object;
  10:         34698        1110336  java.util.Collections$UnmodifiableMap
  11:         40684         976416  org.elasticsearch.painless.Definition$MethodKey
  12:          7135         627880  java.lang.reflect.Method
  13:          6878         623656  [I
  14:          9786         548016  org.elasticsearch.painless.Definition$Struct
  15:         30215         483440  java.lang.Object
  16:          5851         468080  java.lang.reflect.Constructor
  17:          8012         448672  java.lang.invoke.MemberName
  18:           154         365248  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  19:         15518         356192  [Ljava.lang.Class;

查看thread dump:

jcmd 1755 Thread.print
1755:
2021-01-11 23:05:26
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.191-b12 mixed mode):

"elasticsearch[fantuan-tech-node-1][flush][T#1]" #43 daemon prio=5 os_prio=0 tid=0x00007f366c02a800 nid=0x743 waiting on condition [0x00007f36442e6000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c66614a8> (a org.elasticsearch.common.util.concurrent.EsExecutors$ExecutorScalingQueue)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.LinkedTransferQueue.awaitMatch(LinkedTransferQueue.java:737)
        at java.util.concurrent.LinkedTransferQueue.xfer(LinkedTransferQueue.java:647)
        at java.util.concurrent.LinkedTransferQueue.take(LinkedTransferQueue.java:1269)
        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)

查看VM.flags:

jcmd 1755 VM.flags
1755:
-XX:+AlwaysPreTouch -XX:CICompilerCount=2 -XX:CMSInitiatingOccupancyFraction=75 -XX:ErrorFile=logs/hs_err_pid%p.log -XX:GCLogFileSize=67108864 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=data -XX:InitialHeapSize=1073741824 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=87228416 -XX:MaxTenuringThreshold=6 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=87228416 -XX:NumberOfGCLogFiles=32 -XX:OldPLABSize=16 -XX:OldSize=986513408 -XX:-OmitStackTraceInFastThrow -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:ThreadStackSize=1024 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseFastUnorderedTimeStamps -XX:+UseGCLogFileRotation -XX:+UseParNewGC

二、jmap

jmap用于打印一个进程、可执行core文件、远程debug服务的堆内存信息,用于堆内存相关的排查,用法如下:

  • jmap [ options ] pid
  • jmap [ options ] executable core
  • jmap [ options ] [ pid ] server-id@ remote-hostname-or-IP

当进程运行于一个64位的虚拟机的话,需要使用jmap -J-d64 -heap pid,参数如下:

  • pid Java进程ID
  • executable 生成核心转储的java可执行文件
  • core 核心文件
  • remote-hostname-or-IP 远程debug服务器的名称或者IP
  • server-id 唯一ID,假如一台主机上多个远程debug服务,用于区分

options参数有如下可选项:

  • 无可选项 默认打印共享对象映射信息。
  • -dump:[live,] format=b,file=filename 打印Java堆内存信息,生成名字为filename,格式为hprof的文件,live参数是可选的,如果指定了则只dump出acitve objects。
  • -finalizerinfo 打印关于等待结束的对象的信息。
  • -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
  • -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量
  • -clstats 打印classloader,父classloader以及所加载的类的数量以及大小。
  • -F 当使用jmap -dump或者jamp -histo打印无响应的时候使用-F强制打印。不支持live可选项。
  • -h 打印帮助信息
  • -help 打印帮助信息
  • -Jflag 传递标志给Java虚拟机。

三、jstack

jstack用于打印某个进程、核心文件或者远程debug服务器的线程栈信息,在排查多线程问题时非常方便。

  • jstack [ options ] pid
  • jstack [ options ] executable core
  • jstack [ options ] [ server-id@ ] remote-hostname-or-IP

参数说明如下:

  • pid 进程ID
  • executable 产生core dump的java可执行文件
  • core 打印出的core文件
  • remote-hostname-or-IP 远程debug服务器的名称或者IP
  • server-id 唯一ID,假如一台主机上多个远程debug服务,用于区分

Options参数可选项如下:

  • -F 当使用jstack -l pid没有响应的时候,使用-F强制打印栈信息。
  • -l 打印关于锁的额外的信息。
  • -m 打印具有Java和本机C/C++帧的混合模式的堆栈信息,请注意-m无法用于remote debug server
  • -h 打印帮助信息
  • -help 打印帮助信息

四、jstat

jstat用于打印JVM的统计信息,可以显示出虚拟机进程中的类加载信息,内存和垃圾收集,JIT编译等信息,在排查JVM垃圾收集相关问题时非常有用,也是使用频率很高的一个工具,用法如下

jstat [ generalOption | outputOptions vmid [interval [s|ms] ] [count] ]
  • generalOption 输入的参数可选项,使用-help或者-options可查询相关可选项
  • outputOptions 输出的参数可选项
  • vmid 进程ID
  • interval [s|ms] 间隔的个时间
  • count 打印的次数,缺省的时候是打印无数次

generalOption的常见选项如下:

1、-class : 打印classloader的行为和统计信息

$ jstat -class 14998
Loaded   Bytes    Unloaded Bytes   Time
54958  116718.7    464      633.7   183.61
  • Loaded 加载class的数量
  • Bytes class字节大小
  • Unloaded 未加载class的数量
  • Bytes 未加载class的字节大小
  • Time 加载花费的时间

2、-compiler:Hotspot JIT编译器行为和统计信息

$ jstat -compiler 14998
Compiled Failed Invalid Time    FailedType  FailedMethod
36902      5       0     253.24       1     com/intellij/codeInspection/bytecodeAnalysis/ConstractAnalysis ProcessState
  • Compiled 编译数量
  • Failed 编译失败数量
  • Invalid 非法的类数量
  • Time 编译耗时
  • FailedType 失败类型
  • FailedMethod 失败方法的全限定名

3、-gc: 垃圾回收器的行为和统计信息

$ jstat -gc 14998

输出参数的一些说明如下:

  • S0C survivor0区的总容量
  • S1C survivor1去的总容量
  • S0U survivor0区已使用的容量
  • S1U survivor1区已使用的容量
  • EC Eden区的总容量
  • EU Eden区已使用的容量
  • OC Old区的总容量
  • OU Old区已使用的容量
  • PC 当前perm区的容量(KB)
  • PU 当前perm区已使用的容量(KB)
  • YGC 新生代垃圾回收次数
  • YGCT 新生代垃圾回收时间
  • FGC 老年代垃圾回收次数
  • FGCT 老年代垃圾回收时间
  • GCT 垃圾回收总消耗时间

4、-gccapacity:与-gc类似,但是会输出Java堆各区域的容量信息

$ jstat -gccapacity 14998
  • NGCMN 新生代占用的最小的空间
  • NGCMX 新生到占用的最大的空间
  • OGCMN 老年代占用的最小空间
  • OGCMX 老年代占用的最大的空间
  • OGC 当前老年代的容量(KB)
  • OC 当前老年代的空间(KB)
  • PGCMN perm占用的最小空间
  • PGCMX perm占用的最大空间

5、-gcutil:垃圾回收概述信息

$ jstat -gcutil 14998

S0   S1   E    O     M     CCS   YGC YGCT  FGC FGCT   GCT
0.00 0.00 9.67 43.77 94.08 90.88 183 5.836 27  4.589 10.425
  • survivor0区当前使用比例
  • survivor1区当前使用比例
  • Eden区当前使用比例
  • Old区当前使用比例
  • Metaspace区当前使用比例
  • CCS压缩使用的比例
  • YGC 年轻代垃圾回收次数
  • FGC 老年代垃圾回收次数
  • FGCT 老年代垃圾回收消耗时间
  • GCT 垃圾回收消耗总时间
  • -gccause 垃圾回收概述信息,与-gcutil内容一样,只是多附加了最近两次垃圾回收的原因,LGCC代表最近垃圾回收的原因,GCC代表当前垃圾回收的原因。

6、-gcnew:新生代行为和统计信息

7、-gcnewcapacity: 新生代容量统计

8、-gcold: 老年代和永久代行为和统计信息

9、-gcoldcapacity :老年代容量统计

10、-gcpermcapacity :永生代容量统计

11、-printcompilation: HotSpot编译方法统计

Tags:

标签列表
最新留言