参考:
JVM调优参数大全及G1GC调优
java g1垃圾收集器优化参考

1. 概述

JVM 启动参数分为三类

类别说明
标准参数(-)所有的 JVM 实现都必须实现这些参数的功能,而且向后兼容;
非标准参数(-X)这些参数不是虚拟机规范规定的。因此,不是所有VM的实现(如:HotSpot,JRockit,J9等)都支持这些配置参数。
非稳定参数(-XX)这些参数是虚拟机规范中规定的。这些参数指定虚拟机实例在运行时的各种行为,从而对虚拟机的运行时性能有很大影响。

对于-XX类型的配置选项,虚拟机规范有一些惯例,针对不同的平台虚拟机也会提供不同的默认值。

  1. 对于布尔(Boolean)类型的配置选项,通过-XX:+<option>来开启,通过-XX:-<option>来关闭。
  2. 对于数字(Numberic)类型的配置选项,通过-XX:<option>=<number>来配置。<number>后面可以携带单位字母,比如: 'k'或者'K'代表千字节,'m'或者'M'代表兆字节,'g'或者'G'代表千兆字节。
  3. 对于字符串(String)类型的配置选项,通过-XX:<option>=<string>来配置。这种配置通过用来指定文件,路径或者命令列表。

2. 标准参数

-verbose:class 打印每个class信息
-verbose:gc 打印每次gc信息

3. 非标准参数

-Xloggc:filename 设置GC log文件的位置 -Xloggc:log/gc.log
-Xms大小 设置堆的初始化大小 -Xmx2048m =-XX:InitialHeapSize
-Xmx大小 设置堆的最大大小 -Xms1024m =-XX:MaxHeapSize 一般Xms=Xmx,防止扩容和缩容
-Xmn大小 设置年轻代大小(初始化和最大) -Xmn256m
-XX:NewSize -XX:MaxNewSize 分别指定年轻代的初始化和最大大小,建议年轻代占堆大小的1/4 ~ 1/2
-Xss大小 设置线程栈大小 -Xss1m =-XX:ThreadStackSize

4. 不稳定参数

-XX:ErrorFile=文件 设置错误日志路径 -XX:ErrorFile=./hs_err_pid%p.log %p为当前进程号
-XX:OnError=命令 错误发生时执行命令 -XX:OnError="gcore %p;dbx - %p"
-XX:OnOutOfMemoryError=命令 内存溢出时执行命令
-XX:MaxDirectMemorySize=size 设置直接内存最大值 -XX:MaxDirectMemorySize=100m 默认为0 当直接内存达到设置的最大值会FullGC
-XX:ObjectAlignmentInBytes=alignment 设置java对象的内存对齐,默认是8字节
-XX:ThreadStackSize 设置线程栈大小 -XX:ThreadStackSize=1m = -Xss
-XX:-UseBiasedLocking 禁用偏向锁 默认开启,不禁用 如果使用的是大量的没有竞争的同步,使用偏向锁会提升性能
-XX:-UseCompressedOops 禁用压缩指针堆内存小于32G时默认开启 开启后,对象引用是32位而不是64位,可以提升性能。只有64位的jvm才生效
-XX:+DoEscapeAnalysis 开启逃逸分析 默认开启
-XX:+Inline 开启方法内联 默认开启
-XX:InlineSmallCode=大小 设置应内联的已编译方法的最大代码大小,只有小于此数值的才会内联 默认1000字节
-XX:MaxInlineSize=大小 设置要内联方法的最大字节码大小 默认35字节
-XX:+OptimizeStringConcat 开启字符串连接优化 默认开启
-XX:+PrintInlining 打印方法内联 默认关闭,需和-XX:+UnlockDiagnosticVMOptions 一起使用
-XX:-TieredCompilation 关闭分层编译 默认开启
-XX:+HeapDumpOnOutOfMemoryError  OOM时堆内存dump到当前目录
-XX:HeapDumpPath=路径 设置堆内存dump的路径 -XX:HeapDumpPath=/var/java_pid%p.hprof
-XX:+UnlockDiagnosticVMOptions 开启jvm诊断功能选项

垃圾回收相关参数

-XX:+AggressiveHeap 开启堆最优化设置 默认关闭
-XX:+CMSClassUnloadingEnabled 当使用CMS垃圾收集器时,允许类卸载 默认开启
-XX:CMSExpAvgFactor=percent 指定垃圾收集消耗的时间百分比 默认这个数是25%,就是25
-XX:CMSInitiatingOccupancyFraction=percent 设置CMS回收开始的老年代百分比 默认-1,任何的负值表示会使用-XX:CMSTriggerRatio选项来定义这个百分比数
-XX:+CMSScavengeBeforeRemark 在CMS重新标记之前执行ygc操作  默认关闭 在remark时间过长时可以开启;开启减少remark的STW时间
-XX:CMSTriggerRatio=percent 设置CMS开始的百分比 默认80,((100 - MinHeapFreeRatio) + (double)( CMSTriggerRatio * MinHeapFreeRatio) / 100.0) / 100.0=92%
-XX:+UseCMSCompactAtFullCollection  在FULL GC的时候,对年老代的压缩
-XX:CMSFullGCsBeforeCompaction=0  上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩,
-XX:MinHeapFreeRatio=percent GC之后堆内存最小剩余百分比,如果小于此值,则自动扩容 默认40%
-XX:MaxHeapFreeRatio=percent GC之后堆内存最大剩余百分比,如果小于此值,则自动缩容 默认70%
-XX:ParallelGCThreads=threads 设置Parallel GC的线程数 默认根据cpu个数,<=8,则使用8个,>8个3+5N/81台服务器只有1个jvm时使用默认值较好,如果有n个jvm,cpu个数 / n比较合适
-XX:ConcGCThreads=个数 并发GC的线程数 默认值取决于cpu个数 ConcGCThreads = (ParallelGCThreads + 3)/4
-XX:+DisableExplicitGC 使System.gc()显式gc失效 默认不开启,
-XX:G1HeapRegionSize=size 当使用G1收集器时,设置java堆被分割的region大小 1M~32M默认根据堆内存最优化设置
-XX:+G1PrintHeapRegions 打印G1收集器收集的区域  默认关闭
-XX:G1ReservePercent=percent  设置堆内存保留大小,以防晋升失败 0~50 默认10%
-XX:InitialHeapSize=size 堆初始大小 =-Xms
-XX:MaxHeapSize=size 堆最大大小 =-Xmx
-XX:InitialSurvivorRatio=ratio 设置伊甸园区和幸存区初始比例 默认为8:1
-XX:SurvivorRatio=ratio 设置伊甸园区和幸存区比例 默认为8:1  8:1:1
XX:TargetSurvivorRatio YGC之后,幸存区期望百分比 默认 50%
XX:InitiatingHeapOccupancyPercent=percent 堆占用达到多少开始并发垃圾回收 只有并发垃圾回收器生效
-XX:MaxGCPauseMillis=time GC最大暂停时间 ms 默认没有最大暂停时间
-XX:MetaspaceSize=size 元空间多次扩容后超过此值就会full gc 默认大约20M 元空间使用本地内存。 尽量设置足够,避免因为这个区域内存不够引发Full GC
-XX:MaxMetaspaceSize=size 设置元空间最大大小 默认不限制 建议和MetaspaceSize一样大,一般256M
-XX:NewSize=size 设置年轻代初始大小 建议年轻代占堆大小的1/4 ~ 1/2
-XX:MaxNewSize=size 设置年轻代最大大小 默认根据最大效能分配
-XX:MaxTenuringThreshold=threshold 最大晋升年龄,从年轻代到老年代 默认:15 - 并行回收器 6 - CMS
-XX:NewRatio=ratio 设置老年代和新生代比例 默认2 老年代 : (伊甸园 + 2个幸存区)
-XX:+PrintGC 打印GC信息 默认关闭
-XX:+PrintGCDetails 打印GC详细信息 默认关闭
-XX:+PrintTenuringDistribution 打印晋升分配
-XX:+ScavengeBeforeFullGC Full gc之前先ygc 默认开启
-XX:+UseTLAB 年轻代使用线程局部缓存 默认开启  效率高
-XX:TLABSize=size 设置初始化thread-local allocation buffer (TLAB)大小
-XX:+UseAdaptiveSizePolicy  JDK 1.8 默认使用 UseParallelGC 垃圾回收器,该垃圾回收器默认启动了 AdaptiveSizePolicy
-XX:+UseParallelGC 年轻代使用并行回收器
-XX:+UseParallelOldGC 老年代使用并行回收器
-XX:+UseParNewGC 为配置CMS,年轻代使用ParNew回收器,CMS会默认开启
-XX:+UseConcMarkSweepGC 使用CMS回收器
-XX:+UseG1GC 使用G1回收器
-XX:+UseGCOverheadLimit 限制GC的运行时间,通过统计GC时间来预测是否要OOM了,提前抛出异常,防止OOM发生 并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存。用来避免内存过小造成应用不能正常工作
-XX:+UseStringDeduplication 开启字符串去重 G1回收器生效
-XX:AutoBoxCacheMax=20000 加大Integer Cache
-XX:+PrintPromotionFailure 知道是多大的新生代对象晋升到老生代失败从而引发Full GC时的。

5. 查看 jvm 参数值

将参数打印到 gc 日志

-XX:+PrintFlagsInitial 是打印所有的默认参数设置
-XX:+PrintFlagsFinal 是打印最终值,如果某个默认值被新值覆盖,显示新值
-XX:+PrintCommandLineFlags 是打印那些被新值覆盖的项

查看正在运行的 jvm 参数

#查看所有的参数,用法:jinfo -flags <进程id>
[root@node01 bin]# jps
6346 Jps
6219 Bootstrap
 
[root@node01 bin]# jinfo -flags 6219
Attaching to process ID 6219, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.141-b15
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=31457280 -XX:MaxHeapSize=488636416 -XX:MaxNewSize=162529280 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=10485760 -XX:OldSize=20971520 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -Djava.util.logging.config.file=/tmp/apache-tomcat-7.0.57/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/tmp/apache-tomcat-7.0.57/endorsed -Dcatalina.base=/tmp/apache-tomcat-7.0.57 -Dcatalina.home=/tmp/apache-tomcat-7.0.57 -Djava.io.tmpdir=/tmp/apache-tomcat-7.0.57/temp

#查看某一参数的值,用法:jinfo -flag <参数名> <进程id>
[root@node01 bin]# jinfo -flag MaxHeapSize 6219
-XX:MaxHeapSize=488636416

6. 日志参数汇总

G1 为例

6.1 打印 class 信息

打印出加载和卸载的 class

-verbose:class 打印每个class信息
[Loaded java.text.ParsePosition from /Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre/lib/rt.jar]
[Unloading class java.lang.invoke.LambdaForm$MH/1516626417 0x00000007c0764828]

6.2 打印 gc日志

打印简单的 gc 日志

-verbose:gc
 -XX:+PrintGC

两个作用一样,一个标准,一个不标准,后面的可能会过时。

[GC (Allocation Failure)  60237K->8665K(196608K), 0.0038008 secs]
[GC (Metadata GC Threshold)  37697K->7851K(196608K), 0.0031347 secs]
[Full GC (Metadata GC Threshold)  7851K->7106K(196608K), 0.0165075 secs]
[GC (GCLocker Initiated GC)  58818K->8863K(190464K), 0.0013060 secs]
[GC (Allocation Failure)  60582K->10582K(194048K), 0.0015308 secs]
[GC (Allocation Failure)  57174K->12637K(194048K), 0.0018156 secs]
[GC (Allocation Failure)  59229K->13172K(195072K), 0.0018287 secs]
[GC (Allocation Failure)  61300K->14068K(194560K), 0.0021674 secs]
[GC (Allocation Failure)  62196K->15668K(195072K), 0.0026067 secs]

6.3 打印到文件

-Xloggc:filename //设置GC log文件的位置 -Xloggc:log/gc.log

6.4 打印详细日志

-XX:+PrintGCDetails //打印GC详细信息 默认关闭, 开启此选项无需开启 -XX:+PrintGC
1.074: [GC pause (Metadata GC Threshold) (young) (initial-mark), 0.0033032 secs]
   [Parallel Time: 2.6 ms, GC Workers: 13]
      [GC Worker Start (ms): Min: 1073.9, Avg: 1074.0, Max: 1074.1, Diff: 0.2]
      [Ext Root Scanning (ms): Min: 0.6, Avg: 0.7, Max: 0.8, Diff: 0.2, Sum: 8.9]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.5]
         [Processed Buffers: Min: 0, Avg: 1.2, Max: 4, Diff: 4, Sum: 15]
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.5]
      [Object Copy (ms): Min: 1.5, Avg: 1.6, Max: 1.7, Diff: 0.2, Sum: 21.2]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3]
         [Termination Attempts: Min: 1, Avg: 28.8, Max: 34, Diff: 33, Sum: 374]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [GC Worker Total (ms): Min: 2.4, Avg: 2.4, Max: 2.5, Diff: 0.2, Sum: 31.6]
      [GC Worker End (ms): Min: 1076.4, Avg: 1076.4, Max: 1076.4, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.1 ms]
   [Other: 0.5 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.4 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.1 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 4096.0K(106.0M)->0.0B(112.0M) Survivors: 14.0M->8192.0K Heap: 21.3M(200.0M)->12.0M(200.0M)]
 [Times: user=0.02 sys=0.01, real=0.00 secs]

6.5 打印时间戳

真实时间

-XX:+PrintGCDateStamps【打印GC日志附带时间戳】
2022-06-17T18:03:17.794-0800: [GC pause (G1 Evacuation Pause) (young), 0.0068952 secs]

jvm 启动时间

-XX:+PrintGCTimeStamps
10828.000: [GC (Allocation Failure) 2019-11-04T17:52:07.130+0800: 10828.000: [ParNew

6.6 文件滚筒

-Xloggc:/data/logs/java/gc.log 【GC日志的存储路径(前缀)】
-XX:+UseGCLogFileRotation【GC日志文件开启滚动存储】
-XX:NumberOfGCLogFiles=5【GC日志文件最多保留5个】
-XX:GCLogFileSize=30M【每个GC日志文件最大30M,超过30M,生成新的文件】

6.7 打印 gc 前后堆信息

-XX:+PrintHeapAtGC【GC之前和GC之后的堆的内存使用情况要打印出来】
{Heap before GC invocations=7 (full 0):
 garbage-first heap   total 204800K, used 128638K [0x00000007b3800000, 0x00000007b3900640, 0x00000007c0000000)
  region size 1024K, 120 young (122880K), 15 survivors (15360K)
 Metaspace       used 30563K, capacity 32004K, committed 32128K, reserved 1077248K
  class space    used 4083K, capacity 4376K, committed 4480K, reserved 1048576K
2022-06-17T18:06:18.299-0800: [GC pause (G1 Evacuation Pause) (young), 0.0080804 secs]
   [Parallel Time: 4.4 ms, GC Workers: 13]
      [GC Worker Start (ms): Min: 1845.6, Avg: 1845.7, Max: 1845.8, Diff: 0.2]
      [Ext Root Scanning (ms): Min: 0.1, Avg: 0.3, Max: 1.9, Diff: 1.8, Sum: 3.3]
      [Update RS (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 1.1]
         [Processed Buffers: Min: 0, Avg: 1.2, Max: 3, Diff: 3, Sum: 16]
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.3, Diff: 0.3, Sum: 1.6]
      [Object Copy (ms): Min: 2.4, Avg: 3.7, Max: 3.9, Diff: 1.5, Sum: 47.8]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.5]
         [Termination Attempts: Min: 1, Avg: 57.6, Max: 74, Diff: 73, Sum: 749]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
      [GC Worker Total (ms): Min: 4.1, Avg: 4.2, Max: 4.3, Diff: 0.2, Sum: 54.6]
      [GC Worker End (ms): Min: 1849.9, Avg: 1849.9, Max: 1849.9, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.2 ms]
   [Other: 3.5 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 3.2 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.2 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.1 ms]
   [Eden: 105.0M(105.0M)->0.0B(105.0M) Survivors: 15.0M->15.0M Heap: 125.6M(200.0M)->25.9M(200.0M)]
Heap after GC invocations=8 (full 0):
 garbage-first heap   total 204800K, used 26487K [0x00000007b3800000, 0x00000007b3900640, 0x00000007c0000000)
  region size 1024K, 15 young (15360K), 15 survivors (15360K)
 Metaspace       used 30563K, capacity 32004K, committed 32128K, reserved 1077248K
  class space    used 4083K, capacity 4376K, committed 4480K, reserved 1048576K
}
 [Times: user=0.05 sys=0.00, real=0.01 secs]

6.8 打印程序运行时间

gc 过程中,程序中断时间

-XX:+PrintGCApplicationStoppedTime 打印gc过程中 程序中断的时间
2022-06-17T18:09:59.105-0800: Total time for which application threads were stopped: 0.0084858 seconds, Stopping threads took: 0.0000207 seconds

gc 过程中,程序未中断时间

-XX:+PrintGCApplicationConcurrentTime 打印gc过程 程序未中断时间
2022-06-17T18:12:22.390-0800: Application time: 1.0010271 seconds

6.9 打印引用日志

-XX:+PrintReferenceGC 用来跟踪系统内的(softReference)软引用,(weadReference)弱引用,(phantomReference)虚引用,显示引用过程
2022-06-17T18:14:44.098-0800: [GC pause (G1 Evacuation Pause) (young)2022-06-17T18:14:44.104-0800: [SoftReference, 0 refs, 0.0000174 secs]2022-06-17T18:14:44.104-0800: [WeakReference, 6045 refs, 0.0003452 secs]2022-06-17T18:14:44.105-0800: [FinalReference, 824 refs, 0.0003694 secs]2022-06-17T18:14:44.105-0800: [PhantomReference, 0 refs, 1 refs, 0.0000064 secs]2022-06-17T18:14:44.105-0800: [JNI Weak Reference, 0.0000277 secs], 0.0071997 secs]

6.10 打印 gc 原因

-XX:+PrintGCCause 产生GC的原因,在JDK8已默认打开
1.074: [GC pause (Metadata GC Threshold) (young) (initial-mark), 0.0033032 secs]

6.11 打印晋升失败日志

-XX:+PrintPromotionFailure 如果有新生代对象晋升到老生代失败出现的FULL GC,打开这个日志可以看到更详细的信息

6.12 打印晋升日志

-XX:+PrintTenuringDistribution 在每次新生代GC时,打印出幸存区中对象的年龄分布。
[GC pause (G1 Evacuation Pause) (young)
Desired survivor size 7864320 bytes, new threshold 5 (max 15)
- age   1:    2687304 bytes,    2687304 total
- age   2:    1982192 bytes,    4669496 total
- age   3:      77848 bytes,    4747344 total
- age   4:    2441456 bytes,    7188800 total
- age   5:    1220824 bytes,    8409624 total
, 0.0078400 secs]