目录
前言:
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 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-非必看
一般没什么用,线上也不会让你开这个端口
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仅在第一次使用设定值,后续则自动调整.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)