GC调优配置参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GC调优配置参数相关的知识,希望对你有一定的参考价值。

参考技术A 一、JVM调优主要是调整下面两个指标

1. 停顿时间 :垃圾收集器做垃圾回收中断应用执行的时间。 -XX:MaxGCPauseMillis

2. 吞吐量 :垃圾收集的时间和总时间的占比:1/(1+n),吞吐量计算公式为1-1/(1+n), 吞吐量越大,证明性能越好。 -XX:GCTimeRatio=n

二、GC调优步骤

1. 打印GC日志

        -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:./gc.log

       Tomcat则直接加在JAVA_OPTS变量里

* 分析日志得到关键性指标

* 分析GC原因,调优JVM参数(工具:gceasy,GCViewer)

2. GC常用参数

堆栈设置

    -Xss:每个线程的栈大小

    -Xms:初始堆大小,默认物理内存的1/64

    -Xmx:最大堆大小,默认物理内存的1/4

    -Xmn:新生代大小

    -XX:NewSize:设置新生代初始大小

    -XX:NewRatio:默认2,表示新生代占老年代的1/2,占整个堆内存的1/3

    -XX:SurivivorRatio:默认8,表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存

    -XX:MetaspaceSize:设置元空间大小

    -XX:MaxMetaspaceSize:设置元空间最大允许大小,默认不受限制,JVM Metaspace会进行动态扩展

垃圾回收统计信息

    -XX:+PrintGC

    -XX:+PrintGCDetails

    -XX:+PrintGCTimeStamps

    -Xloggc:filename

收集器设置:

    -XX:+UseSerialGC:设置串行收集器

    -XX:+UseParallelGC:设置并行收集器

    -XX:+UseParallelOldGC:老年代使用并行收集器

    -XX:+UseParNewGC:在新生代使用并行收集器

    -XX:+UseConcMarkSweepGC:设置CMS并行收集器

    -XX:UseG1GC:设置G1收集器

并行收集器设置:

     -XX:ParallelGCThreads:设置用于垃圾回收的线程数

    -XX:MaxGCPauseMillis:设置并行收集最大暂停时间

    -XX:GCTimeRatio:设置垃圾回收时间占程序运行时间的百分比

    -XX:YongGenerationSizeIncrement:年轻代GC后扩容的比例,默认是20%

CMS收集器设置

    -XX:+UseConcMarkSweepGC:设置CMS并发收集器

    -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况

    -XX:ParallelGCThreads:设置并发收集器的线程数

    -XX:CMSFullGCsBeforeCompanction:设定进行多少次CMS垃圾回收后,进行一次内存压缩

    -XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收

    -XX:UseCMSInitiatingOccupancyOnly:表示只在到达阈值的时候,才进行CMS回收

    -XX:+CMSIncrementalMode:设置为增量模式,适用于单CPU情况

    -XX:ParallelCMSThreads:设定CMS的线程数量

    -XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发

    -XX:+UseCMSCompactAtFullConllection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理

G1收集器设置

    -XX:+UseG1GC:使用G1收集器

    -XX:ParallelGCThreads:设置并发收集器的线程数

    -XX:G1HeapRegionSize:制定分区大小(1MB~32MB,必须是2的幂),默认将整个堆划分为2048个分区

    -XX:GCTimeRatio:吞吐量大小,0-100的整数(默认9),值为n则系统将花费不超过1/(1+n)的时间用于垃圾回收

    -XX:MaxGCPauseMillis:目标暂停时间(默认200ms)

    -XX:G1NewSizePercent:新生代内存初始空间(默认堆的5%)

    -XX:G1MaxNewSizePercent:新生代内存最大空间

    -XX:TargetSurvivorRatio:Survivor填充容量(默认50%)

    -XX:MaxTenuringThreshold:最大任期阈值(默认15%)

    -XX:InitiatingHeapOccupancyPercen:老年代占空间超过整堆比IHOP阈值(默认45%),超过则进行混合收集

    -XX:G1HeapWastePercent:堆废物百分比(默认5%)

jvm调优具体参数配置

3.JVM参数

    在JVM启动参数中,可以设置跟内存、垃圾回收相关的一些参数设置,默认情况不做任何设置JVM会工作的很好,但对一些配置很好的Server和具体的应用必须仔细调优才能获得最佳性能。通过设置我们希望达到一些目标:

  • GC的时间足够的小
  • GC的次数足够的少
  • 发生Full GC的周期足够的长

  前两个目前是相悖的,要想GC时间小必须要一个更小的堆,要保证GC次数足够少,必须保证一个更大的堆,我们只能取其平衡。

   (1)针对JVM堆的设置,一般可以通过-Xms -Xmx限定其最小、最大值,为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,我们通常把最大、最小设置为相同的值
   (2)年轻代和年老代将根据默认的比例(1:2)分配堆内存,可以通过调整二者之间的比率NewRadio来调整二者之间的大小,也可以针对回收代,比如年轻代,通过 -XX:newSize -XX:MaxNewSize来设置其绝对大小。同样,为了防止年轻代的堆收缩,我们通常会把-XX:newSize -XX:MaxNewSize设置为同样大小

   (3)年轻代和年老代设置多大才算合理?这个我问题毫无疑问是没有答案的,否则也就不会有调优。我们观察一下二者大小变化有哪些影响

  • 更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC
  • 更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率
  • 如何选择应该依赖应用程序对象生命周期的分布情况:如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。但很多应用都没有这样明显的特性,在抉择时应该根据以下两点:(A)本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例1:2也是这个道理 (B)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响Full GC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间

  (4)在配置较好的机器上(比如多核、大内存),可以为年老代选择并行收集算法: -XX:+UseParallelOldGC ,默认为Serial收集

  (5)线程堆栈的设置:每个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,对大多数应用而言这个默认值太了,一般256K就足用。理论上,在内存不变的情况下,减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。

  (4)可以通过下面的参数打Heap Dump信息

  • -XX:HeapDumpPath
  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -Xloggc:/usr/aaa/dump/heap_trace.txt

    通过下面参数可以控制OutOfMemoryError时打印堆的信息

  • -XX:+HeapDumpOnOutOfMemoryError

 请看一下一个时间的Java参数配置:(服务器:Linux 64Bit,8Core×16G)

 

 JAVA_OPTS="$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/aaa/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G"

经过观察该配置非常稳定,每次普通GC的时间在10ms左右,Full GC基本不发生,或隔很长很长的时间才发生一次

通过分析dump文件可以发现,每个1小时都会发生一次Full GC,经过多方求证,只要在JVM中开启了JMX服务,JMX将会1小时执行一次Full GC以清除引用,关于这点请参考附件文档。

 

以上是关于GC调优配置参数的主要内容,如果未能解决你的问题,请参考以下文章

面试题:JVM 配置常用参数和常用 GC 调优策略

常用jvm参数配置

JVM 配置常用参数和常用 GC 调优策略

JVM 配置常用参数和常用 GC 调优策略

JVM面试问题系列:JVM 配置常用参数和常用 GC 调优策略

jvm调优具体参数配置