性能调优案例
1 JVM参数调优
目的:事前预防,事前准备
jps -v 获取程序的jvm相关参数(建议值):
前台(4核8G内存) JDK1.8
-server -Xms4g -Xmx4g -Xmn2g -Xss768k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -verbose:gc -XX:+PrintGCDetails -Xloggc:${CATALINA_BASE}/logs/gc.log -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${CATALINA_BASE}/logs
后台(4核8G内存) JDK1.8
-server -Xms4g -Xmx4g -Xmn2g -Xss768k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -verbose:gc -XX:+PrintGCDetails -Xloggc:${CATALINA_BASE}/logs/gc.log -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${CATALINA_BASE}/logs
各参数介绍
-server: JVM的server模式,区别于client模式
-Xms4g -Xmx4g: JVM堆内存的最小堆大小、最大堆大小
💡为什么Xms和Xmx要设置一样大?
避免在垃圾回收的时候,将占用的内存还给操作系统。若-Xms2g -Xmx4g,在垃圾回收的时候发现很多对象可被回收,则会将对象回收,且jvm内存压倒2g,这样2g用完后,会再向操作系统申请内存,这样会耗时。总结就是:避免反复向操作系统申请内存。
一启动就要分配最小堆大小的空间:-XX:+AlwaysPreTouch
-Xmn2g: 年轻代大小
-Xss768k: 线程的堆栈大小,JDK1.5+每个线程堆栈大小为1M,减少每个线程的堆栈大小有利于增加应用可开启的线程数
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m: 设置Metaspace的初始大小和最大值,JDK1.8+使用Metaspace,设置这个值有利于减缓应用启动时fullGC次数,因为JVM在申请扩容Metaspace时如果超过了MetaspaceSize就会触发fullGC jdk1.8元数据区、jdk1.7永久代
相对的,JDK1.7以下使用-XX:PermSize=256m -XX:MaxPermSize=256m来设置Perm区大小;
-XX:+UseParNewGC: 使用多线程并行收集对年轻代进行GC
-XX:+UseConcMarkSweepGC: 使用CMS收集器对年老代进行GC,CMS收集器优势在于应用停顿时间少,适用于不能忍受长时间停顿的前台应用;
-XX:+CMSClassUnloadingEnabled: 在使用CMS收集器进行垃圾回收时同时清理持久代不再使用的class
-XX:+UseCMSInitiatingOccupancyOnly: CMS默认基于运行时收集的数据来启动CMS垃圾收集周期,开启这个参数来手动指定JVM通过CMSInitiatingOccupancyFraction的值进行垃圾收集策略;
-XX:CMSInitiatingOccupancyFraction=80 : 默认CMS是在年老代占满80%的时候开始进行CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值;