最近项目要生产上线,正在做压测性能测试,开始进行一些性能瓶颈分析,记得上一次做性能分析优化,还是国网项目,针对Kafka,Canal,ES,服务,数据库等一系列的排查分析,后面打算补一下总结内容,感兴趣的可以看我后期的总结。本次先总结一下最基础的相关命令及详解
常用到的命令主要有jstack、jstat、jmap、jinfo等
1、jinfo命令
jinfo全称Configuration Info for Java,是用来查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。开发人员可能不知道某一个具体的Java虚拟机参数的默认值。通过 jinfo工具,开发人员可以很方便地找到Java虚拟机参数的当前值。
jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值, 甚至可以在运行时修改部分参数,并使之立即生效。并不是所有参数都支持动态修改。参数只有被标记 manageable的flag可以被实时修改。这个修改能力是极其有限的。
下面简单介绍一下常用命令:
1) jinfo flags <PID>
jinfo flags <PID>
可以看到不主动配置JVM参数时,系统默认的一些配置信息,然后我们指定配置后查看
-Xms512m -Xmx1024m
jinfo –flags <PID>
2) jinfo -sysprops <PID>
jinfo -sysprops <PID>
查看java系统参数
2、jmap命令
jmap能够打印给定Java进程、核心文件或远程DEBUG服务器的共享对象内存映射或堆内存的详细信息。如果给定的进程运行在64位虚拟机上,则必须指定 -J-d64选项,例如jmap -J-d64 -heap pid。
参数说明
<no option>
当不使用选项时,jmap打印共享对象映射。
对于加载到目标JVM中的每个共享对象,将打印其开始地址、映射大小和共享对象文件的完整路径。如图:
1) -dump
-dump:[live],format=b,file=<filename>.hprof <PID>
将Java堆以hprof二进制格式转储到filename文件中。live是可选参数,如果指定,则只转储堆中的活动对象。
可以使用jhat (Java Heap Analysis Tool)工具来读取分析生产dump文件。启动jhat服务器
访问显示如图:
Jhat分析内容,下次有机会再说明,先往下走
2) -finalizerinfo <PID>
jmap -finalizerinfo <PID>
打印等待结束的对象的信息。
3) -heap <PID>
jmap -heap <PID>
打印堆摘要
这个命令相对用的较多,具体说明记录一下
使用的gc垃圾收集器
一、Heap Configuration(堆的配置)
MinHeapFreeRatio | 空闲堆空间的最小百分比,值的区间为0到100,默认值为 40。 计算公式为:HeapFreeRatio =(CurrentFreeHeapSize / CurrentTotalHeapSize) * 100。 如果当前HeapFreeRatio < MinHeapFreeRatio,则需要进行堆扩容,扩容的时机应该在每次垃圾回收之后。 |
MaxHeapFreeRatio | 空闲堆空间的最大百分比,值的区间为0到100,默认值为 70。 计算公式为:HeapFreeRatio =(CurrentFreeHeapSize / CurrentTotalHeapSize) * 100。 如果HeapFreeRatio > MaxHeapFreeRatio,则需要进行堆缩容,缩容的时机应该在每次垃圾回收之后。 |
MaxHeapSize | 堆空间允许的最大值。 |
NewSize | 新生代堆空间的默认值。 |
MaxNewSize | 新生代堆空间允许的最大值。 |
OldSize | 老年代堆空间的默认值。 |
NewRatio | 新生代(2个Survivor区和Eden区 )与老年代(不包括永久区)的堆空间比值。 |
SurvivorRatio | 两个Survivor区和Eden区的堆空间比值,默认是8,表示 S0 : S1 :Eden = 1:1:8。 |
MetaspaceSize | 元空间的默认值 |
CompressedClassSpaceSize | 压缩类空间大小 |
MaxMetaspaceSize | 元空间允许的最大值 |
G1HeapRegionSize | 在使用 G1 垃圾回收算法时,JVM会将Heap空间分隔为若干个Region,该参数用来指定每个 Region 空间的大小 |
- 二、Heap Usage(堆的使用情况)
-
Heap Usage(堆的使用情况) PS Young Generation (Eden + 1 Survivor Space) 新生代的使用情况 Eden Space Eden区的使用情况
From Space From Survivor区的使用情况 To Space to Survivor区的使用情况 PS Old Generation 老年代的使用情况 说明:
capacity表示该区域的总容量
used表示已使用的容量
free表示该区域还剩余容量
used表示该区域的使用比例
4) -histo[:live] <PID>
jmap -histo <PID>
打印堆的直方图。对于每个Java类,将打印对象数量、内存大小(以字节为单位)和完全限定类名。VM内部类名以'*'前缀打印,即打印出来的类名前带*的是VM的内部类。如果指定了live子选项,则只统计活动对象。可以输出到文件中打开。
num:序号
instances:实例数量
bytes:占用空间大小
class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]
5) -clstats <PID>
jmap -clstats <PID>
打印类加载器的统计信息。对于每个类加载器,它的名称、活动状态、地址、父加载器以及已加载的类的数量和大小都将被打印出来。也会打印出internned string的数量和大小。
6) -F
如果pid没有响应,则使用jmap -dump 或 jmap -histo命令。遇到过不能open file的时候,可以通过加-F,强制输出。
7) -help or -h
打印jmap命令的帮助信息。
8) -J<flag>
将<flag>传递给运行jmap的Java虚拟机
3、jstack命令
该命令比较常用,用来检测死锁,CPU高等
用jstack查找死锁
1) 查找死锁
jstack -l <PID>
说明:
"Thread-5" 线程名
prio=5 优先级=5
tid= 0x00007fcae8185000线程id
nid= 0xbf8线程对应的本地线程标识nid
runnable 线程状态
可以看到是哪里出现了死锁,所在的类及其行数
2) 远程连接jvisualvm
启动普通的jar程序JMX端口配置:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8899
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
tomcat的JMX配置
JAVA_OPTS=-Dcom.sun.management.jmxremote.port=8899
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
jvisualvm远程连接服务需要在远程服务器上配置host(连接ip 主机名),并且要关闭防火墙
3) 输出文件分析
jstack –l <PID> > jatack.log
printf "%x\n" <tid>
根据PID输出快照线程,找到CPU最高的线程,10进制转16进制,找对应的线程 状态分析代码
如:
grep "dca" jstack.log -A 20
4、jstat命令
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]
1) 垃圾回收统计
jstat -gc <pid>
最常用,可以评估程序内存使用及GC压力整体情况
更多的是使用,多久打印一次,共打印多少次
jstat -gc <pid> <interval> <count>
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小(元空间)
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间,单位s
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间,单位s
GCT:垃圾回收消耗总时间,单位s
2) 堆内存统计
jstat -gccapacity <PID>
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数
3) 新生代垃圾回收统计
jstat -gcnew <PID>
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
4) 新生代内存统计
jstat -gcnewcapacity <PID>
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数
5) 老年代垃圾回收统计
jstat -gcold <PID>
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
6) 老年代内存统计
jstat -gcoldcapacity <PID>
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
7) 元数据空间统计
jstat -gcmetacapacity <PID>
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
8) 占比查看
jstat -gcutil <PID>
S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
ok,基本上常用的和不常用的都简单记录了下,也不是时时刻刻都在做性能优化,在需要的时候能有个对照就OK了 ,下一个就是针对具体的问题进行查找跟踪分析了,如果不借助工具的情况下,可以通过上述这些命令组合进行分析。