性能调优案例

性能调优案例

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次数的话,可以适当调高此值;