一、实现Tomcat的gc优化
Tomcat运行java web程序,如果只是满足功能要求,那么无需调节性能。但是,应用上生产后,稍微一点的优化都会产生产生巨大的效率提升。所以,Tomcat的优化是必须的,其中gc优化又是关键一条。
二、环境
tomcat8.0+
jdk1.8
三、设置Tomcat不同gc策略并且对比结果
1.设置并行垃圾回收器
修改bin/catalina.sh文件,添加下面的到250行左右的位置。
#年轻代、老年代均使用并行收集器,初始堆内存64M,最大堆内存512M
JAVA_OPTS="-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms64m -Xmx512m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:/home/hadoop/server/apache-tomcat-app/logs/gc.log"
备注:-Xloggc垃圾回收日志位置,最好指定绝对路径,如果使用../的相对路径,经过测试无法输出gc.log文件,而且本身会报错找不到该路径。
2.获得gc日志上传gceasy.io进行分析
2.1 系统所消耗的时间大于用户时间(自身没有发现)
如果在报告中显示System Time greater than User Time,系统所消耗的时间大于用户时间,这反应出的服务器的性能存在瓶颈,调度CPU等资源所消耗的时间要长一些
2.2查看JVM内存大小
2.3查看Key Performance Indicators,查看吞吐量和垃圾回收平均时间
2.4 GC总次数统计
结果分析:
(1)年轻代gc有52次,比较多,说明年轻代设置不合适,比较小,需要调整。
(2)Fullgc有2次,可以选择调整或者不调整。
2.5统计网站给出的可能原因
年轻代内存不足导致频繁jc。
3.优化配置,提升年轻代大小
JAVA_OPTS="-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms128m -Xmx1024m -XX:NewSize=64m -XX:MaxNewSize=256m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:/home/hadoop/server/apache-tomcat-app/logs/gc.log"
4.获取优化后gc日志,同样上传gceasy.io进行分析
4.1 查看常规JVM配置
4.2 查看关键KPI(Key Performance Indicators)
最大回收时间减少,总体回收次数也从57减少到38,起到一定优化作用。
4.3 查看GC总数统计
无论minor gc还是full gc都是有减少。所以,说明优化有效。
4.4 查看最终分析原因
5.后续优化
5.1 设置G1垃圾回收器
#设置了最大停顿时间100毫秒,初始堆内存128m,最大堆内存1024m
JAVA_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -Xms128m -Xmx1024m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:../logs/gc.log"
5.2 JVM最佳配置,仅作参考
JAVA_OPTS="-Dfile.encoding=UTF-8-server -Xms1024m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:MaxTenuringThreshold=10-XX:NewRatio=2 -XX:+DisableExplicitGC"
参数说明
file.encoding 默认文件编码
-Xmx1024m 设置JVM最大可用内存为1024MB
-Xms1024m 设置JVM最小内存为1024m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-XX:NewSize 设置年轻代大小
-XX:MaxNewSize 设置最大的年轻代大小
-XX:PermSize 设置永久代大小
-XX:MaxPermSize 设置最大永久代大小
-XX:NewRatio=4 设置年轻代(包括Eden和两个Survivor区)与终身代的比值(除去永久代)。设置为4,则年轻代与终身代所占比值为1:4,年轻代占整个堆栈的1/5
-XX:MaxTenuringThreshold=0 设置垃圾最大年龄,默认为:15。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
-XX:+DisableExplicitGC 这个将会忽略手动调用GC的代码使得System.gc()的调用就会变成一个空调用,完全不会触发任何GC。
三、参考
1. 史上最强Tomcat8性能优化