1.调整内存
调整内存是最基本的手段,不过要结合业务来调,个人的经验就是临时对象多,new的多,对象存活的时间比较短。就把young区给整大了,尽量让gc都发生在young区里面,适合及时响应和低延迟的应用
#设置堆内存为1024m
#设置年轻代⼤⼩为512m,默认是堆内存的1/3
#设置初始的Metaspace⼤⼩为64m
JAVA_OPTS="-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms1024m -Xmx1024m -
XX:NewSize=512m -XX:MetaspaceSize=64m -XX:+PrintGCDetails -
XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -
Xloggc:../logs/gc.log -Dcom.sun.management.jmxremote -
Dcom.sun.management.jmxremote.port=9999 -
Dcom.sun.management.jmxremote.authenticate=false -
Dcom.sun.management.jmxremote.ssl=false"
2.更换G1收集器
在jdk1.8中,更新的g1收集器是性能更好的,主要是它会默认不分区的去实现GC,效果会比分区的收集器好,更加的简洁。适用与大内存低延迟的场景,例如设置了6G或者8G的内存,还要保持低延迟。
JAVA_OPTS="-XX:+UseG1GC -Xmx1024m -XX:MetaspaceSize=64m -
XX:MaxGCPauseMillis=100 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -
XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:../logs/gc.log -
Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -
Dcom.sun.management.jmxremote.authenticate=false -
Dcom.sun.management.jmxremote.ssl=false"
//实战使用的参数,仅供参考
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -Xmx6G -
XX:MetaspaceSize=128m -XX:MaxGCPauseMillis=100 -XX:G1NewSizePercent=50
-XX:G1MaxNewSizePercent=80
//-XX:G1NewSizePercent
//设置要⽤作年轻代⼤⼩最⼩值的堆百分⽐。默认值是 Java 堆的 5%。(实验性质参数)
//-XX:G1MaxNewSizePercent
//设置要⽤作年轻代⼤⼩最⼤值的堆⼤⼩百分⽐。默认值是 Java 堆的 60%。(实验性质
参数)
3.ZGC收集器
这个jdk11的收集器,也是目前感觉上效果最好的,不过要更换版本,在真实项目并未试过。
JAVA_OPTS="-XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xmx1024m -
XX:MetaspaceSize=64m -Xlog:gc*:../logs/gc.log -Dcom.sun.management.jmxremote -
Dcom.sun.management.jmxremote.port=9999 -
Dcom.sun.management.jmxremote.authenticate=false -
Dcom.sun.management.jmxremote.ssl=false"
关于调优的建议:
1.不要直接上生产环境,生产环境的JVM也一定要做参数设置,不要用默认的。
2.参数的设置与业务息息相关。
3.对于内存中对象临时存在居多的情况,将年轻代调⼤⼀些。如果是G1或ZGC,不需要设定。
4.试着用gceasy看报告来分析问题。
5.对于低延迟的应⽤建议使⽤G1或ZGC垃圾收集器。
6.不要将焦点全部聚焦jvm参数上,影响性能的因素有很多,⽐如:操作系统、tomcat本身的参数等。