FullGC应该控制在几小时或者几天发生一次,每次400毫秒(不是很良好)
younggc每天1000次左右(还好),每分钟1次左右,每次younggc在50毫秒左右
1、调优原则
- 最大、最小设置一样
- 程序运行起来后,通过visualvm,arthas查看占用多少内存,向上调优,预留20%以上的空间
- 通过perfma 分析堆日志
常用的调试工具还有: HSDB
2、常用工具
2.1、jstack
- 定位死锁
-
找出占用cpu最高的线程堆栈信息
-
top -p 例如进程id为19663
-
安H,获取每个线程的内存情况
-
找到内存和cpu高的线程tid,比如19664
-
转为十六进制得到0x4cd0,此为线程的十六进制表示
-
执行jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中4cd0这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法
-
2.2、jinfo
1)、查看jvm参数
jinfo -flags pid
2)、查看系统参数
jinfo -sysprops pid
2.3、jstat
jstat -gc pid
堆内存统计
jstat -gccapacity pid
新生代垃圾回收统计
jstat -gcnew pid
老年代垃圾回收统计
jstat -gcold pid
jstat -gc pid 1000 10 // 表示每隔1000毫秒执行一次,共执行10次
2.4、jmap
jmap -histo pid >./log.log
jmap -heap pid >./log.log
堆内存dump堆的快照信息
jmap -dump:fomart=b,file=eureka.log pid
也可设置内存溢出自动导出dump文件(内存很大时可能导不出来)
1)、-XX:+HeapDumpOnOutOfMemoryError
2)、-XX:+HeapDumpPath=./ (路径)
2.5、jvisualvm
远程连接jvisualvm
启动普通的jar程序JMX端口配置
java -Dcom.sun.management.jmxremote.port=8888 -Djava.rmi.server.hostname=192.168.50.60 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar mircr.jar
PS:
-Dcom.sun.management.jmxremote.port 为远程机器的JMX端口
-Djava.rmi.server.hostname 为远程机器ip
tomcatJMX配置:在catalina.sh文件里的最后一个JAVA_OPTS的赋值语句下一行新增如下配置
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote=8888 -Djava.rmi.server.hostname=192.168.50.50 -Dcom.sun.management.jmxremote.ssl=falseb -Dcom.sun.management.jmxremote.authenticate=false"
优化示例
-Xms1536m -Xmx1536m -Xmn1024m -Xss256k -XX:SurivorRatio=6 -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M
-XX:+UseParNewGC -XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupanyFraction=92 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGG
生产环境通常jvm添加
-XX:PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\jvm.dump
线上通过 -XX:+DisableExplicitGG参数禁用System.gc();