一、GC-常用参数配置
1.通用参数
-Xms 堆内存初始大小(默认为物理内存的1/64(<1GB);默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制),是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢。
-Xmx 堆内存最大大小(默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制),是指设定程序运行期间最大可占用的内存大小,如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。
-Xmn 新生代大小 (注意:此处的大小是(eden+ 2 survivor space)。与jmap -heap中显示的New gen是不同的。整个堆大小=新生代大小 + 老生代大小 + 永久代大小。在保证堆大小不变的情况下,增大新生代后,将会减小老生代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。)
-Xss 线程大小(每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。应根据应用的线程所需内存大小进行适当调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。一般小的应用, 如果栈不是很深, 应该是128k够用的,大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"-Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了。),是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。
-XX:+UserG1GC 指定使用G1垃圾回收器
-XX:SurvivorRatio eden区和一个survivor区比例 eden/survivor 注意S区有两个(新生代中Eden区域与Survivor区域的容量比值,默认值为8。两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。)
-XX:MaxTenuringThreshold 新生代进入老年代的年龄(即在新生代躲过了几次GC)
-XX:-UseAdaptiveSizePolicy 关闭Survivor区大小动态变化
-XX:PretenureSizeThreshold 大对象直接晋升老年代阈值
-XX:+DisableExplicitGC 禁止显示执行GC 不允许代码触发GC 例如 System.gc()
2. OOM
-XX:+HeapDumpOnOutOfMemoryError 表示当JVM发生OOM时,自动生成DUMP文件。
-XX:HeapDumpPath=${目录} 表示生成DUMP文件的路径,也可以指定文件名称
示例:
java -server -Xms7g -Xmx7g -Xmn1792m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -Dfile.encoding=UTF-8
-XX:+UseG1GC -XX:MaxGCPauseMillis=200
-XX:+ParallelRefProcEnabled -Xloggc:/workspace/carkey/AppHelloOpenApiService/latest//logs/gc.log -XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/workspace/carkey/AppHelloOpenApiService/latest//logs/heapdump.hprof
3. GC日志
-XX:+PrintGCApplicationStoppedTime
输出GC造成应用暂停的时间
示例:
java -server -Xms7g -Xmx7g -Xmn1792m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -Dfile.encoding=UTF-8
-XX:+UseG1GC -XX:MaxGCPauseMillis=200
-XX:+ParallelRefProcEnabled
-Xloggc:/workspace/carkey/AppHelloOpenApiService/latest//logs/gc.log
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/workspace/carkey/AppHelloOpenApiService/latest//logs/heapdump.hprof
4. CMS回收器:
-XX:+UseConcMarkSweepGC 启用CMS回收器
-XX:CMSInitiatingOccupancyFaction 指定老年代的空间使用率达到xx触发full gc 因为并发收集的时候可能会有新对象进入老年代
-XX:+UserCMSCompactAtFullCollection 使用CMS触发Full GC之后进行压缩 (避免内存碎片)
-XX:CMSFullGCBeforeCompaction 执行多少次Full GC后进行压缩 默认0
-XX:+CMSParallelInitialMarkEnabled CMS回收”初始标记“阶段开启多线程并发执行
-XX:CMSScavengeBeforeRemark 在CMS”重新标记“阶段之前 尽量执行一次Young GC
5. G1回收器
-XX:+UserG1GC 指定使用G1辣鸡回收器
-XX:G1HeapRegionSize 指定Region的大小
-XX:G1NewSizePercent 设置新生代初始占比 默认5%
-XX:MaxTenuringThreshold 新生代进入老年代的年龄(即在新生代躲过了几次GC)
-XX:InitiatingHeapOccupancyPercent 老年代占据了堆内存的Percent%时,就会尝试触发一个新生代+老生代一期回收的混合回收阶段 即Mixed GC 默认值45%
-XX:MaxGCPauseMills G1执行GC的时候最多可以让系统停顿多长时间 默认200ms
-XX:G1MixedGCCountTarget 在一次混合回收的过程中,最后一个阶段执行混合回收的次数 默认8次
-XX:G1HeapWastePercent 当空闲的Region数量达到了堆内存的Percent%,此时就会立即停止混合回收,意味着本次混合回收就结束了 默认值5%(在混合回收的时候,对Region回收都是基于复制算法进行的,都是把要回收的Region里的存活对象放入其他region,然后这个Region中的垃圾对象全部清理调,这样的话在回收过程就会不断空出来新的Region)
-XX:G1MixedGCLiveThresholdPercent 回收Region时,必须是存活对象低于Percent%的Region才可以进行回收 默认85% (如果存活对象过多,复制算法成本会很高)
java -server -Xms7g -Xmx7g -Xmn1792m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled -Xloggc:/workspace/carkey/AppHelloOpenApiService/latest//logs/gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/workspace/carkey/AppHelloOpenApiService/latest//logs/heapdump.hprof
6. 元数据区
-XX:TraceClassLoading :追踪类加载
-XX:TraceClassUnloading: 追踪类卸载
7.永久代 perm gen
- -XX:PermSize:设置永久代(perm gen)初始值。默认值为物理内存的1/64。
- -XX:MaxPermSize:设置持久代最大值。物理内存的1/4。
为了避免Perm区满引起的full gc,建议开启CMS回收Perm区选项:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
默认CMS是在tenured generation(老年代)沾满68%的时候开始进行CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值:-XX:CMSInitiatingOccupancyFraction=80
遇到两种fail引起full gc:Prommotion failed和Concurrent mode failed时:
8. 大量反射场景
-XX:SoftRefLRUPolicyMSPerMB 提高这个数值就是让反射过程中JVM自动创建的软引用的一些类的class对象不要被随便回收
加上自己的一些笔记
补充:
MetaspaceSize和MaxMetaspaceSize的理解
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m
MaxMetaspaceSize用于设置metaspace区域的最大值,这个值可以通过mxbean中的MemoryPoolBean获取到,如果这个参数没有设置,那么就是通过mxbean拿到的最大值是-1,表示无穷大。
-
MetaspaceSize表示metaspace首次使用不够而触发FGC的阈值,只对触发起作用,原因是:垃圾搜集器内部是根据变量
_capacity_until_GC
来判断metaspace区域是否达到阈值的,初始化代码如下所示:
JAVA_OPTS="-server -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:SurvivorRatio=4 -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log -Djava.awt.headless=true -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15"
解析:
Xms,即为jvm启动时得JVM初始堆大小,Xmx为jvm的最大堆大小,xmn为新生代的大小,permsize为永久代的初始大小,MaxPermSize为永久代的最大空间。
java -server -Xms7g -Xmx7g -Xmn1792m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m
-Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled
-Xloggc:/workspace/carkey/AppHelloOpenApiService/latest//logs/gc.log -XX:+PrintGCDateStamps
-XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/workspace/carkey/AppHelloOpenApiService/latest//logs/heapdump.hprof
三、java启动参数共分为三类
其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;
其二是非标准参数(又称为扩展参数 )(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;
其三是非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用;
一、标准参数(-)
标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;
标准参数中比较有用的:
verbose
-verbose:class
输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。
-verbose:gc
输出每次GC的相关情况。
-verbose:jni
输出native方法调用的相关情况,一般用于诊断jni调用错误信息。
二、非标准参数又称为扩展参数 (-X):
一般用到最多的是
-Xms512m 设置JVM最小可用内存为512m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmx512m ,设置JVM最大可用内存为512m。
-Xmn200m:设置年轻代大小为200M。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
-Xloggc:file
与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。
若与verbose命令同时出现在命令行中,则以-Xloggc为准。
-Xprof
跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。
示例:
java -server -Xms7g -Xmx7g -Xmn1792m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled -Xloggc:/workspace/carkey/AppHelloOpenApiService/latest//logs/gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/workspace/carkey/AppHelloOpenApiService/latest//logs/heapdump.hprof -Dcom.sun.management.jmxremote.port=5555 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote=true -DAPPID=AppHelloOpenApiService -DbasicConf.host=https://pt-basicconf.hellobike.cn -Dapollo.meta=http://pt-apollometa.hellobike.cn:10080 -Dsoa.group=online_test -Dsoa.register.url=pt-soazk1.hellobike.cn:2181,pt-soazk2.hellobike.cn:2181,pt-soazk3.hellobike.cn:2181 -Dsoa.auth.url=https://pt-basicconf.hellobike.cn -Dsoa.server.tag.ignore=false -Dsoa.server.tag.mandatory=false -Dowl.metrics.kafka.servers=pt-kafka1.ttbike.com.cn:9092,pt-kafka2.ttbike.com.cn:9092 -Denv=pt -Dsoa.server.port=80 -Djava.io.tmpdir=/workspace/carkey/AppHelloOpenApiService/latest//temp/ -Duser.dir=/workspace/carkey/AppHelloOpenApiService/latest/ -Dproject.name=open-api -Dcsp.sentinel.config.file=classpath:sentinel.properties -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -classpath /workspace/carkey/AppHelloOpenApiService/latest//conf:/workspace/carkey/AppHelloOpenApiService/latest//lib/*: com.hellobike.openapi.deploy.OpenApiApplication
三、非Stable参数(-XX)
此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用;
用-XX作为前缀的参数列表在jvm中可能是不健壮的,SUN也不推荐使用,后续可能会在没有通知的情况下就直接取消了;但是由于这些参数中的确有很多是对我们很有用的,比如我们经常会见到的-XX:PermSize、-XX:MaxPermSize等等;
首先来介绍行为参数:
参数及其默认值 |
描述 |
-XX:-DisableExplicitGC |
禁止调用System.gc();但jvm的gc仍然有效 |
-XX:+MaxFDLimit |
最大化文件描述符的数量限制 |
-XX:+ScavengeBeforeFullGC |
新生代GC优先于Full GC执行 |
-XX:+UseGCOverheadLimit |
在抛出OOM之前限制jvm耗费在GC上的时间比例 |
-XX:-UseConcMarkSweepGC |
对老生代采用并发标记交换算法进行GC |
-XX:-UseParallelGC |
启用并行GC |
-XX:-UseParallelOldGC |
对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用 |
-XX:-UseSerialGC |
启用串行GC |
-XX:+UseThreadPriorities |
启用本地线程优先级 |
上面表格中黑体的三个参数代表着jvm中GC执行的三种方式,即串行、并行、并发;
串行(SerialGC)是jvm的默认GC方式,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿;
并行(ParallelGC)是指GC运行时,对应用程序运行没有影响,GC和app两者的线程在并发执行,这样可以最大限度不影响app的运行;
并发(ConcMarkSweepGC)是指多个线程并发执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大;
性能调优参数列表:
参数及其默认值 |
描述 |
-XX:LargePageSizeInBytes=4m |
设置用于Java堆的大页面尺寸 |
-XX:MaxHeapFreeRatio=70 |
GC后java堆中空闲量占的最大比例 |
-XX:MaxNewSize=size |
新生成对象能占用内存的最大值 |
-XX:MaxPermSize=64m |
老生代对象能占用内存的最大值 |
-XX:MinHeapFreeRatio=40 |
GC后java堆中空闲量占的最小比例 |
-XX:NewRatio=2 |
新生代内存容量与老生代内存容量的比例 |
-XX:NewSize=2.125m |
新生代对象生成时占用内存的默认值 |
-XX:ReservedCodeCacheSize=32m |
保留代码占用的内存容量 |
-XX:ThreadStackSize=512 |
设置线程栈大小,若为0则使用系统默认值 |
-XX:+UseLargePages |
使用大页面内存 |
我们在日常性能调优中基本上都会用到以上黑体的这几个属性;
调试参数列表:
参数及其默认值 |
描述 |
-XX:-CITime |
打印消耗在JIT编译的时间 |
-XX:ErrorFile=./hs_err_pid<pid>.log |
保存错误日志或者数据到文件中 |
-XX:-ExtendedDTraceProbes |
开启solaris特有的dtrace探针 |
-XX:HeapDumpPath=./java_pid<pid>.hprof |
指定导出堆信息时的路径或文件名 示例:-XX:HeapDumpPath=/workspace/carkey/AppHelloOpenApiService/latest//logs/heapdump.hprof |
-XX:-HeapDumpOnOutOfMemoryError |
当首次遭遇OOM时导出此时堆中相关信息 示例:-XX:+HeapDumpOnOutOfMemoryError |
-XX:OnError="<cmd args>;<cmd args>" |
出现致命ERROR之后运行自定义命令 |
-XX:OnOutOfMemoryError="<cmd args>;<cmd args>" |
当首次遭遇OOM时执行自定义命令 |
-XX:-PrintClassHistogram |
遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同 |
-XX:-PrintConcurrentLocks |
遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同 |
-XX:-PrintCommandLineFlags |
打印在命令行中出现过的标记 |
-XX:-PrintCompilation |
当一个方法被编译时打印相关信息 |
-XX:-PrintGC |
每次GC时打印相关信息 |
-XX:-PrintGC Details |
每次GC时打印详细信息 |
-XX:-PrintGCTimeStamps |
打印每次GC的时间戳 |
-XX:-TraceClassLoading |
跟踪类的加载信息 |
-XX:-TraceClassLoadingPreorder |
跟踪被引用到的所有类的加载信息 |
-XX:-TraceClassResolution |
跟踪常量池 |
-XX:-TraceClassUnloading |
跟踪类的卸载信息 |
-XX:-TraceLoaderConstraints |
跟踪类加载器约束的相关信息 |
参考文档:https://blog.csdn.net/lbh199466/article/details/103144831/
https://www.cnblogs.com/junzi2099/p/7827448.html
http://xstarcd.github.io/wiki/Java/JVM_GC.html