Java的GC参数介绍

介绍Java的常见的GC参数

Posted by qin4zhang on September 9, 2019

注意

想法及时记录,实现可以待做。

GC参数介绍

了解了GC的类型和常用的算法后,设置GC参数,对于JVM启动是有很大的作用的。

常见参数介绍

java官方文档

java命令行启动支持的选项有标准选项、非标准选项和高级选项。

标准选项适合Java虚拟机(JVM)的所有实现的支持。它们用于常见的操作,例如检查JRE版本、设置类路径、启用详细输出等等。

非标准选项是特定于Java HotSpot Virtual Machine的通用选项,因此它们不能保证得到所有JVM实现的支持,并且可能会发生变化。这些选项以-X开头。

高级选项不建议随意使用。这些是用于调优Java HotSpot Virtual Machine操作的特定领域的开发人员选项,这些操作通常有特定的系统需求,可能需要对系统配置参数的特权访问。

它们也不能保证得到所有JVM实现的支持,并且可能会发生变化。高级选项以-XX开头。

布尔选项用于启用默认禁用的特性或禁用默认启用的特性。这些选项不需要参数。Boolean -XX选项使用加号(-XX:+OptionName)启用,使用减号(-XX:-OptionName)禁用。

标准选项

  1. -agentpath:pathname[=options]

加载由绝对路径名指定的本机代理库。该选项相当于-agentlib,但使用库的完整路径和文件名。

  1. -Dproperty=value

置系统属性值。属性变量是一个不带空格的字符串,表示属性的名称。value变量是一个表示属性值的字符串。如果value是一个带空格的字符串,则用引号将其括起来(例如-Dfoo=”foo bar”)。

  1. -jar filename

执行封装在JAR文件中的程序。filename参数是一个JAR文件的名称,其中的清单包含一行Main-Class:classname的形式,它用public static void main(String[] args)方法定义类,该方法作为应用程序的起点。

  1. -verbose:class

显示关于每个装入类的信息。

  1. -verbose:gc

显示关于每个垃圾收集(GC)事件的信息。

非标准选项

这些选项是特定于Java HotSpot虚拟机的通用选项

  1. -Xloggc:filename

设置详细GC事件信息应重定向到的文件以进行日志记录

  1. -Xmnsize

设置年轻代的大小,比如-Xmn256m。不使用-Xmn选项来为年轻代设置堆的初始大小和最大大小,也可以使用-XX:NewSize来设置初始大小,使用-XX:MaxNewSize来设置最大大小。

  1. -Xmssize

设置堆的最小值,比如-Xms600m。

如果不设置此选项,则初始大小将被设置为为老一代和年轻一代分配的大小的总和。年轻代的初始堆大小可以使用-Xmn选项或-XX:NewSize选项设置。

请注意,-XX:InitalHeapSize 选项也可用于设置初始堆大小。 如果它出现在命令行上的 -Xms 之后,则初始堆大小将设置为 -XX:InitalHeapSize 指定的值。

  1. -Xmxsize

分配的堆的最大值,比如-Xmx800m。-Xmx选项等价于-XX:MaxHeapSize

  1. -Xnoclassgc

禁用类的垃圾收集(GC)。这可以节省一些GC时间,从而缩短应用程序运行期间的中断。

当您在启动时指定-Xnoclassgc时,应用程序中的类对象将在GC期间保持不变,并始终被认为是活动的。这可能导致更多内存被永久占用,如果不小心使用,将抛出内存溢出异常。

  1. -Xsssize

线程栈的大小。比如-Xss1m。这个选项相当于-XX:ThreadStackSize

高级运行时选项

这些选项控制Java HotSpot VM的运行时行为。

  1. -XX:+DisableAttachMechanism

启用禁用让工具附加到JVM的机制的选项。默认情况下,该选项是禁用的,这意味着附加机制是启用的,您可以使用jcmd、jstack、jmap和jinfo等工具。

  1. -XX:MaxDirectMemorySize=size

最大的直接内存,或者说堆外内存,比如-XX:MaxDirectMemorySize=100m。New I/O会涉及这块的内存分配。

  1. -XX:ErrorFile=filename

指定在发生不可恢复的错误时将错误数据写入的路径和文件名。默认情况下,该文件在当前工作目录中创建,命名为hs_err_pidd .log,其中pid是导致错误的进程的标识符。

下面的示例演示如何设置默认日志文件(注意,进程的标识符被指定为%p):

-XX:ErrorFile=./hs_err_pid%p.log
-XX:ErrorFile=/var/log/java/java_error_in_xxx_%p.log
  1. -XX:+PrintCommandLineFlags

在GC的时候,打印出现在命令行的JVM标识。

高级可维护性选项

这些选项提供了收集系统信息和执行广泛调试的能力。

  1. -XX:+HeapDumpOnOutOfMemoryError

当抛出java.lang.OutOfMemoryError异常时,通过使用堆分析器(HPROF)启用将Java堆转储到当前目录中的文件。可以使用-XX:HeapDumpPath选项显式设置堆转储文件路径和名称。

默认情况下,这个选项是禁用的,当抛出OutOfMemoryError异常时,堆不会被转储。

  1. -XX:HeapDumpPath=path

当设置-XX:+HeapDumpOnOutOfMemoryError选项时,设置用于写入堆分析程序(HPROF)提供的堆转储的路径和文件名。

默认情况下,在当前工作目录中创建文件,文件名为java_pid%p.hprof其中pid是导致错误的进程的标识符。下面的示例演示如何显式设置默认文件(%p表示当前进程标识符):

-XX:HeapDumpPath=./java_pid_%p.hprof

-XX:HeapDumpPath=/var/log/java/java_heapdump.hprof

高级GC选项

这些选项控制Java HotSpot VM如何执行垃圾收集(GC)。

  1. -XX:+CMSClassUnloadingEnabled

在使用并发标记清除(CMS)垃圾收集器时启用类卸载。该选项在默认情况下是启用的。要禁用CMS垃圾收集器的类卸载,请指定-XX:-CMSClassUnloadingEnabled

  1. -XX:CMSInitiatingOccupancyFraction=percent

设置启动CMS收集周期的老代占用百分比(0到100)。默认值设置为-1。任何负值(包括默认值)都意味着-XX:CMSTriggerRatio用于定义初始化占用率的值。比如-XX:CMSInitiatingOccupancyFraction=20

  1. -XX:+CMSScavengeBeforeRemark

在CMS remark步骤之前启用清除尝试。默认情况下,该选项是禁用的。

  1. -XX:CMSTriggerRatio=percent

设置-XX:MinHeapFreeRatio指定的在CMS收集周期开始之前分配的值的百分比(0到100)。默认值为80%。比如-XX:CMSTriggerRatio=75

  1. -XX:ConcGCThreads=threads

设置用于并发GC的线程数。默认值取决于JVM可用的cpu数量。比如-XX:ConcGCThreads=2

  1. -XX:+DisableExplicitGC

启用禁用对System.gc()调用的处理的选项。该选项在默认情况下是禁用的,这意味着对System.gc()的调用将被处理。如果禁用了对System.gc()的调用的处理,JVM仍然会在必要时执行GC。

  1. -XX:G1HeapRegionSize=size

设置使用垃圾优先(G1)收集器时将Java堆细分为哪些区域的大小。该值可以在1 MB到32 MB之间。默认区域大小是根据堆大小确定的。比如-XX:G1HeapRegionSize=16m

  1. -XX:+G1PrintHeapRegions

允许打印关于G1收集器分配了哪些区域以及回收了哪些区域的信息。默认情况下,该选项是禁用的。

  1. -XX:G1ReservePercent=percent

设置保留为虚假上限的堆的百分比(0 到 50),以减少 G1 收集器升级失败的可能性。 默认情况下,此选项设置为 10%。比如-XX:G1ReservePercent=20

  1. -XX:InitiatingHeapOccupancyPercent=percent

设置启动并发GC周期的堆占用百分比(0到100)。垃圾收集器使用它,它根据整个堆的占用率触发并发GC周期,而不仅仅是一个代(例如,G1垃圾收集器)。缺省情况下,初始值为45%。

  1. -XX:MaxGCPauseMillis=time

设置最大GC暂停时间的目标(以毫秒为单位)。这是一个软目标,JVM将尽最大努力实现它。缺省情况下,没有设置最大暂停时间。比如-XX:MaxGCPauseMillis=500

  1. -XX:MaxMetaspaceSize=size

设置可分配给类元数据的最大本机内存量。默认情况下,大小不受限制。应用程序的元数据量取决于应用程序本身、其他正在运行的应用程序以及系统上可用的内存量。比如-XX:MaxMetaspaceSize=256m

  1. -XX:MaxTenuringThreshold=threshold

设置自适应GC大小调整中使用的最大持久阈值。最大的值是15。并行(吞吐量)收集器的默认值是15,CMS收集器的默认值是6。比如-XX:MaxTenuringThreshold=10

  1. -XX:MetaspaceSize=size

设置已分配的类元数据空间的大小,该类元数据空间将在第一次超出时触发垃圾收集。垃圾收集的这个阈值取决于所使用的元数据的数量。默认大小取决于平台。

  1. -XX:ParallelGCThreads=threads

设置年轻代和年老代中用于并行垃圾收集的线程数。默认值取决于JVM可用的cpu数量。比如-XX:ParallelGCThreads=2

  1. -XX:+PrintAdaptiveSizePolicy

允许打印有关自适应生成大小调整的信息。默认情况下,该选项是禁用的。

  1. -XX:+PrintGC

支持在每个GC上打印消息。默认情况下,该选项是禁用的。

  1. -XX:+PrintGCApplicationConcurrentTime

启用打印自上次暂停(例如GC暂停)以来经过了多少时间。默认情况下,该选项是禁用的。

  1. -XX:+PrintGCApplicationStoppedTime

支持打印暂停(例如GC暂停)持续了多长时间。默认情况下,该选项是禁用的。

  1. -XX:+PrintGCDateStamps

在每个GC上启用打印日期戳。默认情况下,该选项是禁用的。

  1. -XX:+PrintGCDetails

允许在每个GC上打印详细的消息。默认情况下,该选项是禁用的。

  1. -XX:+PrintGCTaskTimeStamps

允许为每个GC工作线程任务打印时间戳。默认情况下,该选项是禁用的。

  1. -XX:+PrintGCTimeStamps

允许在每个GC上打印时间戳。默认情况下,该选项是禁用的。

  1. -XX:+PrintStringDeduplicationStatistics

打印重复数据删除的详细统计信息。默认情况下,该选项是禁用的。请参见-XX:+UseStringDeduplication选项。

  1. -XX:+PrintTenuringDistribution

打印年龄分代的信息。输出示例如下:

Desired survivor size 48286924 bytes, new threshold 10 (max 10)
- age 1: 28992024 bytes, 28992024 total
- age 2: 1366864 bytes, 30358888 total
- age 3: 1425912 bytes, 31784800 total
...
  1. -XX:+ScavengeBeforeFullGC

在每次Full GC之前启用年轻代的GC。该选项在默认情况下是启用的。Oracle建议您不要禁用它,因为在完整GC之前清除年轻代可以减少从老代空间到年轻代空间的对象数量。

要在每次全GC之前禁用年轻代的GC,请指定-XX:-ScavengeBeforeFullGC

  1. -XX:SoftRefLRUPolicyMSPerMB=time

设置软引用对象在最后一次被引用后在堆上保持活动的时间(以毫秒为单位)。默认值是堆中每个空闲兆字节的一秒生命周期。

-XX:SoftRefLRUPolicyMSPerMB选项接受代表当前堆大小(对于Java HotSpot Client VM)或最大可能堆大小(对于Java HotSpot Server VM)的每兆字节毫秒的整数值。

这种差异意味着客户端VM倾向于刷新软引用而不是增加堆,而服务器VM倾向于增加堆而不是刷新软引用。在后一种情况下,-Xmx选项的值对软引用垃圾收集的速度有很大影响。比如-XX:SoftRefLRUPolicyMSPerMB=2500

  1. -XX:SurvivorRatio=ratio

设置伊甸园空间大小和幸存者空间大小之间的比率。默认情况下,该选项设置为8。比如-XX:SurvivorRatio=8

  1. -XX:TLABSize=size

设置 thread-local allocation buffer (TLAB)的初始化大小。比如-XX:TLABSize=512k

  1. -XX:+UseAdaptiveSizePolicy

允许使用自适应的生成大小调整。该选项在默认情况下是启用的。要禁用自适应生成大小调整,请指定-XX:-UseAdaptiveSizePolicy并显式设置内存分配池的大小(参见-XX:SurvivorRatio选项)。

  1. -XX:+UseCMSInitiatingOccupancyOnly

启用使用占用值作为启动CMS收集器的唯一标准。默认情况下,该选项是禁用的,可以使用其他条件。

  1. -XX:+UseConcMarkSweepGC

支持对老年代使用CMS垃圾收集器。当吞吐量(-XX:+UseParallelGC)垃圾收集器无法满足应用程序延迟需求时,Oracle建议您使用CMS垃圾收集器。G1垃圾收集器(-XX:+UseG1GC)是另一种选择。

默认情况下,此选项是禁用的,并且根据机器的配置和JVM的类型自动选择收集器。当启用该选项时,将自动设置-XX:+UseParNewGC选项,您不应该禁用它,因为以下选项组合在JDK 8中已弃用:-XX:+UseConcMarkSweepGC -XX:-UseParNewGC。

  1. -XX:+UseG1GC

启用垃圾优先(G1)垃圾收集器。它是一种服务器风格的垃圾收集器,目标是具有大量RAM的多处理器机器。它以高概率满足GC暂停时间目标,同时保持良好的吞吐量。

对于需要大堆(大小约为6gb或更大)且GC延迟需求有限(稳定且可预测的暂停时间低于0.5秒)的应用程序,推荐使用G1收集器。

  1. -XX:+UseGCOverheadLimit

启用一个策略来限制JVM在抛出OutOfMemoryError异常之前花费在GC上的时间比例。默认情况下,如果超过98%的时间花在垃圾收集上,并且少于2%的堆被恢复,并行GC将抛出OutOfMemoryError。

当堆很小时,可以使用此特性来防止应用程序长时间运行,而几乎没有进展。要禁用该选项,请指定-XX:-UseGCOverheadLimit。

  1. -XX:+UseParallelGC

支持使用并行清除垃圾收集器(也称为吞吐量收集器),通过利用多个处理器来提高应用程序的性能。

默认情况下,此选项是禁用的,并且根据机器的配置和JVM的类型自动选择收集器。如果启用了,那么-XX:+UseParallelOldGC选项将自动启用,除非您显式禁用它。

  1. -XX:+UseParNewGC

支持在年轻代中使用并行线程进行收集。默认情况下,该选项是禁用的。当您设置-XX:+UseConcMarkSweepGC选项时,它将自动启用。

  1. -XX:+UseSerialGC

启用串行垃圾收集器的使用。对于不需要垃圾收集的任何特殊功能的小型简单应用程序,这通常是最佳选择。默认情况下,此选项是禁用的,并且根据机器的配置和JVM的类型自动选择收集器。

  1. -XX:+UseTLAB

支持在年轻代空间中使用 thread-local allocation blocks (TLABs)。该选项在默认情况下是启用的。如果要禁用tlab,请指定-XX:-UseTLAB

Concurrent Mark and Sweep

参数 描述
-XX:+UseCMSInitiatingOccupancyOnly 将占用率作为启动CMS收集操作的标准。
-XX:CMSInitiatingOccupancyFraction=70 设置启动CMS收集周期的CMS生成占用百分比
-XX:CMSTriggerRatio=70 这是CMS生成中在CMS周期开始之前分配的MinHeapFreeRatio的百分比。
-XX:CMSTriggerPermRatio=90 设置启动CMS收集周期之前在CMS永久生成中分配的MinHeapFreeRatio的百分比。
-XX:CMSWaitDuration=2000 使用该参数指定允许CMS等待年轻收集的时间。
-XX:+UseParNewGC 选择对年轻空间收集使用并行算法。
-XX:+CMSConcurrentMTEnabled 允许对并发阶段使用多个线程。
-XX:ConcGCThreads=2 设置用于并发阶段的并行线程数。
-XX:ParallelGCThreads=2 设置要用于STW阶段的并行线程数。
-XX:+CMSIncrementalMode 开启iCMS (incremental CMS)模式。
-XX:+CMSClassUnloadingEnabled 如果不启用此功能,CMS将不会清理永久空间。
-XX:+ExplicitGCInvokesConcurrent 这允许System.gc()触发并发收集,而不是整个垃圾收集周期。
-XX+UseCMSCompactAtFullCollection 在FULL GC的时候, 对年老代的压缩
-XX:+CMSParallelRemarkEnabled 降低标记停顿
-XX:CMSFullGCsBeforeCompaction=2 多少次后进行内存整理
XX:+CMSScavengeBeforeRemark 表示开启或关闭在 CMS 重新标记阶段之前的清除(YGC)尝试,它可以降低 remark 时间,建议加上

CMS示例

-server                                             ## 服务器模式
-Xms2g                                              ## 初始化堆内存大小
-Xmx2g                                              ## 堆内存最大值
-Xmn256m                                            ## 年轻代内存大小,整个JVM内存=年轻代 + 年老代 + 持久代
-Xss256k                                            ## 设置每个线程的堆栈大小
-XX:PermSize=256m                                   ## 持久代内存大小
-XX:MaxPermSize=256m                                ## 最大持久代内存大小
-XX:ReservedCodeCacheSize=256m                      ## 代码缓存,存储已编译方法生成的本地代码
-XX:+UseCodeCacheFlushing                           ## 代码缓存满时,让JVM放弃一些编译代码
-XX:+DisableExplicitGC                              ## 忽略手动调用GC, System.gc()的调用就会变成一个空调用,完全不触发GC
-Xnoclassgc                                         ## 禁用类的垃圾回收,性能会高一点
-XX:+UseConcMarkSweepGC                             ## 并发标记清除(CMS)收集器
-XX:+CMSParallelRemarkEnabled                       ## 启用并行标记,降低标记停顿
-XX:+UseParNewGC                                    ## 对年轻代采用多线程并行回收,这样收得快
-XX:+UseCMSCompactAtFullCollection                  ## 在FULL GC的时候对年老代的压缩,Full GC后会进行内存碎片整理,过程无法并发,空间碎片问题没有了,但提顿时间不得不变长了
-XX:CMSFullGCsBeforeCompaction=3                    ## 多少次Full GC 后压缩old generation一次
-XX:LargePageSizeInBytes=128m                       ## 内存页的大小
-XX:+UseFastAccessorMethods                         ## 原始类型的快速优化
-XX:+UseCMSInitiatingOccupancyOnly                  ## 使用设定的回收阈值(下面指定的70%)开始CMS收集,如果不指定,JVM仅在第一次使用设定值,后续则自动调整
-XX:CMSInitiatingOccupancyFraction=70               ## 使用cms作为垃圾回收使用70%后开始CMS收集
-XX:SoftRefLRUPolicyMSPerMB=50                      ## Soft reference清除频率,默认存活1s,设置为0就是不用就清除
-XX:+AlwaysPreTouch                                 ## 强制操作系统把内存真正分配给JVM
-XX:+PrintClassHistogram                            ## 按下Ctrl+Break后,打印类的信息
-XX:+PrintGCDetails                                 ## 输出GC详细日志
-XX:+PrintGCTimeStamps                              ## 输出GC的时间戳(以基准时间的形式)
-XX:+PrintHeapAtGC                                  ## 在进行GC的前后打印出堆的信息
-XX:+PrintGCApplicationConcurrentTime               ## 输出GC之间运行了多少时间
-XX:+PrintTenuringDistribution                      ## 参数观察各个Age的对象总大小
-XX:+PrintGCApplicationStoppedTime                  ## GC造成应用暂停的时间
-Xloggc:../log/gc.log                               ## 指定GC日志文件的输出路径
-ea                                                 ## 打开断言机制,jvm默认关闭
-Dsun.io.useCanonCaches=false                       ## java_home没有配置,或配置错误会报异常
-Dsun.awt.keepWorkingSetOnMinimize=true             ## 可以让IDEA最小化到任务栏时依然保持以占有的内存,当你重新回到IDEA,能够被快速显示,而不是由灰白的界面逐渐显现整个界面,加快回复到原界面的速度
-Djava.net.preferIPv4Stack=true                     ## 让tomcat默认使用IPv4
-Djdk.http.auth.tunneling.disabledSchemes=""        ## 等于Basic会禁止proxy使用用户名密码这种鉴权方式,反之空就可以使用
-Djsse.enablesSNIExtension=false                    ## SNI支持,默认开启,开启会造成ssl握手警告
-XX:+HeapDumpOnOutOfMemoryError                     ## 表示当JVM发生OOM时,自动生成DUMP文件
-XX:HeapDumpPath=../log                             ## 表示生成DUMP文件的路径,也可以指定文件名称,如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof。  
-XX:-OmitStackTraceInFastThrow                      ## 省略异常栈信息从而快速抛出,这个配置抛出这个异常非常快,不用额外分配内存,也不用爬栈,但是出问题看不到stack trace,不利于排查问题
-Dfile.encoding=UTF-8

G1 – Garbage First

参数 描述
-XX:+MaxGCPauseMills=200 为所需的最长暂停时间设置目标值。默认值是 200 毫秒
-XX:+GCPauseIntervalMills 停顿间隔时间
‐XX:G1HeapRegionSize=n 指定分区大小(1MB~32MB,且必须是2的幂),默认将整堆划分为2048个分区
‐XX:G1NewSizePercent=5 新生代内存初始空间(默认整堆5%)
‐XX:G1MaxNewSizePercent=60 新生代内存最大空间
-XX:ParallelGCThreads=n 并发工作线程数
-XX:ConcGCThreads=n 并行标记的线程数
-XX:InitiatingHeapOccupancyPercent=45 设置触发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。
-XX:G1MixedGCLiveThresholdPercent=65 混合垃圾回收周期中要包括的旧区域设置占用率阈值。默认占用率为 65%
-XX:+UseG1GC
-XX:MaxGCPauseMillis=100
-XX:G1HeapRegionSize=4M
-XX:MaxTenuringThreshold=12
-XX:InitiatingHeapOccupancyPercent=40
-XX:ConcGCThreads=4
-XX:+UseStringDeduplication
-XX:AutoBoxCacheMax=20000
-XX:MetaspaceSize=128m 
-XX:MaxMetaspaceSize=256m
-XX:+PrintPromotionFailure
-XX:+HeapDumpOnOutOfMemoryErro
-XX:HeapDumpPath=${LOGDIR}/java_pid${pid}.hprof
-Xloggc:/data/log/gc-myapp.log 
-verbose:gc 
-XX:+PrintGCDateStamps 
-XX:+PrintGCDetails
-XX:+DisableExplicitGC 

参考

  1. CMS GC启动参数优化配置
  2. JVM系列三:JVM参数设置、分析
  3. Java中9种常见的CMS GC问题分析与解决
  4. G1调优