目录

 

前言:

1.JVM调优基础命令

1.1 Jmap

1.1.1 常用命令

 1.1.2 常用参数

1.1.3 jvisualvm

1.2 jstack

1.2.1 查看进程死锁

1.2.2 远程链接jvisualvm-非必看

1.2.3 查看占用CPU最高的线程堆栈信息-linux服务器

 1.2.4 查看jvm参数和系统参数

 1.3 jstat

2.优化思路


前言:

在看这篇文章之前,强烈推荐各位去看一下《深入理解JAVA虚拟机》,虽然书有些过时,不过里面提到的很多理论和实战总结到现在也是很有用的方法,即使各位可能都做不了系统调优的工作,但能去调试一下平时的IDE或者系统程序什么的也是一种很不错的体验!

1.JVM调优基础命令

1.1 Jmap

jmap查看内存信息:num 序号 #instances实例号 #bytes 占用字节数 class name类名

1.1.1 常用命令

jps --查看进程ID与程序

jps -l #查看具体PID与具体程序

jps -help #jps帮助文档

jmap -histo 14308 >./log.txt #将当前JVM运行线程内容打印输出到log.txt,共有4个参数可查看
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[][])

jmap -heap 14308 #查看堆使用情况

jmap ‐dump:format=b,file=eureka.hprof 14308 #输出dump文件到eureka.hprof文件中

 

 1.1.2 常用参数

‐Xms10M --最小堆大小
‐Xmx10M --最大堆大小

‐XX:+PrintGCDetails --打印GC详细信息
‐XX:+HeapDumpOnOutOfMemoryError 
‐XX:HeapDumpPath=D:\jvm.dump --堆溢出自动导出到D:\jvm.dump文件中

 使用时在程序VM options中添加即可

 堆导出的文件是二进制文件,无法识别,需要使用jvisualVm工具装载查看

1.1.3 jvisualvm

使用jvisualvm打开工具,文件->装入,文件类型选择堆dump文件即可导入。

jvisualvm #打开jvisualvm工具

 

 

1.2 jstack

1.2.1 查看进程死锁

jstack 9272>log.txt #查看线程死锁情况并打印到log.txt文件中查找deadlock关键字
或者使用jvisualvm查看死锁

"Thread-1" 线程名 
prio=5 优先级=5 
tid=0x000000001fa9e000 线程id 
nid=0x2d64 线程对应的本地线程标识nid 
java.lang.Thread.State: BLOCKED 线程状态

1.2.2 远程链接jvisualvm-非必看

如果需要查看远程主机jvm情况可以使用jvisualvm工具,连接上以后需要添加端口号。

 

 

java -Dcom.sun.management.jmxremote.prot=8888 -Djava.rmi.server.hostname=192.168.1.7 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar microservice-eureka-server.jar #启动jar包

#-Dcom.sun.management.jmxremote.port 为远程机器的JMX端口 
#-Djava.rmi.server.hostname 为远程机器IP
tomcat的JMX配置:在catalina.sh文件里的最后一个JAVA_OPTS的赋值语句下一行增加如下配置行 JAVA_OPTS="$JAVA_OPTS ‐Dcom.sun.management.jmxremote.port=8888 ‐Djava.rmi.server.hostname=192.168.1.7 ‐Dcom.sun.ma nagement.jmxremote.ssl=false ‐Dcom.sun.management.jmxremote.authenticate=false"

1.2.3 查看占用CPU最高的线程堆栈信息-linux服务器

16进制网站传送门!!!

jps #查看PID
top -p PID #查看占用CPU最高的进程
H #查看细分占用的java进程,找到占用CPU最大的那个PID
jstack PID|grep -A 10 a75 #打印当前进程中a75进程附近10行的内容,一般能查到有问题的代码;a75是最大的PID的16进制表示,需要自己去网上用转换器转换为16进制

 1.2.4 查看jvm参数和系统参数

jinfo -flags 2630 #查看jvm参数

jinfo -sysprops 2630 #查看系统参数

 1.3 jstat

jstat查看堆的内存使用情况用于统计数据,不过目前看来jstat -gc用的比较多点儿

jstat -gc 2630 #垃圾回收统计
S0C:第一个幸存区的大小,单位KB S1C:第二个幸存区的大小 S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小 EC:伊甸园区的大小 EU:伊甸园区的使用大小 OC:老年代大小 OU:老年代使用大小 MC:方法区大小(元空间) MU:方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间,单位s FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间,单位s GCT:垃圾回收消耗总时间,单位s

jstat -gccapacity 2630 #堆内存使用统计
NGCMN:新生代最小容量 NGCMX:新生代最大容量 NGC:当前新生代容量 S0C:第一个幸存区大小 S1C:第二个幸存区的大小 EC:伊甸园区的大小 OGCMN:老年代最小容量 OGCMX:老年代最大容量 OGC:当前老年代大小 OC:当前老年代大小 MCMN:最小元数据容量 MCMX:最大元数据容量 MC:当前元数据空间大小 CCSMN:最小压缩类空间大小 CCSMX:最大压缩类空间大小 CCSC:当前压缩类空间大小 YGC:年轻代gc次数 FGC:老年代GC次数

jstat -gcnew 2630 #新生代垃圾回收统计
S0C:第一个幸存区的大小 S1C:第二个幸存区的大小 S0U:第一个幸存区的使用大小 S1U:第二个幸存区的使用大小 TT:对象在新生代存活的次数 MTT:对象在新生代存活的最大次数 DSS:期望的幸存区大小 EC:伊甸园区的大小 EU:伊甸园区的使用大小 YGC:年轻代垃圾回收次数 YGCT:年轻代垃圾回收消耗时间

jstat -gcnewcapacity 2630 #新生代内存统计
NGCMN:新生代最小容量 NGCMX:新生代最大容量 NGC:当前新生代容量 S0CMX:最大幸存1区大小 S0C:当前幸存1区大小 S1CMX:最大幸存2区大小 S1C:当前幸存2区大小 ECMX:最大伊甸园区大小 EC:当前伊甸园区大小 YGC:年轻代垃圾回收次数 FGC:老年代回收次数

jstat -gcold 2630 #老年代垃圾回收统计
MC:方法区大小 MU:方法区使用大小 CCSC:压缩类空间大小 CCSU:压缩类空间使用大小 OC:老年代大小 OU:老年代使用大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间

jstat -gcoldcapacity 2630 #老年代内存统计
OGCMN:老年代最小容量 OGCMX:老年代最大容量 OGC:当前老年代大小 OC:老年代大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间

jstat -gcmetacapacity 2630 #元数据空间统计
MCMN:最小元数据容量 MCMX:最大元数据容量 MC:当前元数据空间大小 CCSMN:最小压缩类空间大小 CCSMX:最大压缩类空间大小 CCSC:当前压缩类空间大小 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间

jstat -gcutil 2630 #Eden区统计
S0:幸存1区当前使用比例 S1:幸存2区当前使用比例 E:伊甸园区使用比例 O:老年代使用比例 M:元数据区使用比例 CCS:压缩使用比例 YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数 FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间

2.优化思路

一般都是FullGC频繁才会想起来去调优,调优的时候一般都是让对象进入时是Survivor区的一半大小,让对象在年轻代朝生夕死。至于为什么只能是Survivor区的一半,是因为JVM有一种动态年龄判断机制,当超过S区一半的时候先发生一次GC。这里需要计算几个数值,然后去分析调优

jstat -gc 2630 1000 10 #打印当前线程JVM参数 1000是1秒的意思 10是打印10次

YGC耗时:YGCT/YGC
FGC耗时:FGCT/FGC
年轻代对象速率:观察EU(Eden区使用)
老年代对象增长速率:观察OU使用情况

‐Xms1536M 最小堆大小
‐Xmx1536M 最大堆
‐Xmn512M 年轻代大小
‐Xss256K 线程大小
‐XX:SurvivorRatio=6 Eden:S0:S1=6:1:1
‐XX:MetaspaceSize=256M 元空间大小
‐XX:MaxMetaspaceSize=256M 最大元空间大小
‐XX:+UseParNewGC 年轻代收集器
‐XX:+UseConcMarkSweepGC 老年代收集器
‐XX:CMSInitiatingOccupancyFraction=75 到老年代75%的时候发生FGC
‐XX:+UseCMSInitiatingOccupancyOnly 只是用设定的回收阈值(上面指定的75%),如果不指定,JVM仅在第一次使用设定值,后续则自动调整.

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐