1. G1适用场景

G1从jdk7开始,jdk9被设为默认垃圾收集器;在jdk8就需要指定参数配置,目标就是彻底替换掉CMS。

G1的首要目标是为需要大量内存的系统提供一个保证GC低延迟的解决方案,也就是说堆内存最低在6GB及以上,稳定和可预测的暂停时间小于0.5秒。
如果应用程序具有如下的一个或多个特征,那么将垃圾收集器从CMS或ParallelOldGC切换到G1将会大大提升性能:
(1)Full GC 次数太频繁或者消耗时间太长;
(2)受够了太长的垃圾回收或内存整理时间(0.5-1s);

2. G1垃圾回收方式

2.1 G1的GC类型

1)Ygc:仅处理年轻代region
2)MixedGc:包含所有年轻代以及部分老年代Region。
3)FullGc:全堆扫描,每个Region

2.2 G1的gc原则

G1会在无法分配对象或者巨型对象无法获得连续分区来分配空间时,优先尝试扩展堆空间来获得更多的可用分区。
原则上G1会计算执行GC的时间,并且极力减少花在GC上的时间(包括ygc,mixgc),如果可能,会通过不断扩展堆空间来满足对象分配、转移的需要。

2.3 youngGC(年轻代垃圾回收)

触发:分配一般对象(非巨型对象)时,当所有eden的region使用达到最大阀值并且无法申请足够内存时。
younggc会回收所有Eden以及Survivor区,并且将存活对象复制到Old区以及另一部分的Survivor区。到Old区的标准就是在PLAB中得到的计算结果。因为YoungGC会进行根扫描,所以会stop the world。

2.4 MixGC(混合垃圾回收)

触发:一次YoungGc之后,老年代占据堆内存的百占比超过InitiatingHeapOccupancyPercent(默认45%)时,超过这个值就会触发mixedGC。
混合回收都是基于复制算法进行的,把要回收的Region区存活的对象放入其他Region,然后这个Region全部清理掉,这样就会不断空出来新的Region;
有一个参数-XX:G1HeapWastePercent,默认值5%,即空出来的区域大于整个堆的5%,就会立即停止混合回收了。如正常默认回收次数是8次,但是可能到了4次,空闲Region大于整个堆的5%,就不会再进行后续回收了。

2.5 FullGc(全局垃圾回收)

G1在对象复制/转移失败或者没法分配足够内存(比如巨型对象没有足够的连续分区分配)时,会触发FullGC。开始版本FullGC使用的是stop the world的单线程的Serial Old模式。
JDK10以后,Full GC已经是并行运行,在很多场景下,其表现还略优于 Parallel GC 的并行 Full GC 实现。但是仍然要避免fgc。

3. 最佳实践指导

3.1 不要设置年轻代的大小

通过 -Xmn 显式地指定了年轻代的大小, 会干扰到 G1收集器的默认行为:
(1)G1在垃圾收集时将不再关心暂停时间指标. 所以从本质上说,设置年轻代的大小将禁用暂停时间目标;
(2)G1在必要时也不能够增加或者缩小年轻代的空间. 因为大小是固定的,所以对更改大小无能为力;

3.2 设置 XX:MaxGCPauseMillis=<N>

其值不应该使用平均响应时间,应该考虑使用目标时间的90%或者更小作为响应时间指标. 即90%的用户(客户端)请求响应时间不会超过预设的目标值;

3.3 转移失败

survivors 或 promoted objects 进行GC时如果JVM的heap区不足就会发生提升失败(promotion failure). 堆内存不能继续扩充,因为已经达到最大值了。当使用 -XX:+PrintGCDetails 时将会在GC日志中显示 to-space overflow (to-空间溢出)。该操作很昂贵,原因如下:
1)GC仍继续所以空间必须被释放. 
2)拷贝失败的对象必须被放到正确的位置(tenured in place). 
3)CSet指向区域中的任何 RSets 更新都必须重新生成(regenerated).

避免转移失败的方法:
1)增加保留内存大小, 其默认值是 10;G1保留内存大小,非必须不会使用保留内存;即增大-XX:G1ReservePercent=n
2)更早启动标记周期(marking cycle).即InitiatingHeapOccupancyPercent设置的小一点??
3)增加标记线程(marking threads)的数量. 合理设置-XX:ConcGCThreads=n

3.4 新生代优化-避免短生命对象进入老年代

预估每次Minor GC后存活下来对象的大小,合理的设置Survivor区,同时考虑高峰期间时,动态年龄判断条件的影响,不要让这种短生命周期对象侥幸逃脱进入老年代

3.5 老年代

系统的停顿时间时关键!是核心,要预测停顿时间,并不是越小越好,过小则回收效果不大
即-XX:MaxGCPauseMills参数优化
这个参数是核心点!如果参数设置的值很大,导致系统运行很久,新生代可能都占用了堆内存的60%了,此时才触发新生代GC,那么存活下来的对象可能就会很多,此时就会导致Survivor区域放不下那么多的对象(或是动态年龄判定规则),就会进入老年代中。
如果参数设置过小,即使GC停顿时间很短,但GC频率太大,比如说30秒触发一次新生代gc,每次就停顿30毫秒,这样也是很影响系统性能的。或者GC频率过高,也可能会导致对象很容易就进入了老年代,这样也是有问题;

4. G1相关的参数

4.1 参数说明1

-XX:MaxGCPauseMillis=200 - 设置最大GC停顿时间指标,JVM会尽力实现,但不保证. 默认值为200毫秒.
-XX:InitiatingHeapOccupancyPercent=45 - 如果老年代占据了堆内存的45%的时候,此时会触发一次mixGc。值为0则表示“一直执行GC循环)'. 默认值为45。
-XX:G1MixedGCLiveThresholdPercent:默认值是85%,确定要回收的Region的时候,必须是存活对象低于85%的Region才可以回收。
-XX:G1ReservePercent=n 设置堆内存保留为假天花板的总量,以降低提升失败的可能性. 默认值是 10.
-XX:ConcGCThreads=n 并发垃圾收集器使用的线程数量. 默认值随JVM运行的平台不同而不同.
-XX:+UseG1GC - 让 JVM使用G1垃圾收集器, jdk9被设为默认垃圾收集器;所以如果你的版本比较新则不再需要使用该参数
-XX:MetaspaceSize=256M 元空间,默认20M,确实有点小。
-XX:MaxMetaspaceSize=512M 最大元空间下面参数不建议修改
-XX:G1NewSizePercent=5    设置年轻代占整个堆的最小百分比,默认值是堆的5%。需要开启-XX:UnlockExperimentalVMOptions
-XX:G1MaxNewSizePercent=60    设置年轻代占整个堆的最大百分比,默认值是堆的60%。
-XX:NewRatio=n 新生代与老生代(new/old generation)的大小比例(Ratio). 默认值为 2.
-XX:SurvivorRatio=n eden/survivor 空间大小的比例(Ratio). 默认值为 8.
-XX:MaxTenuringThreshold=n 年轻代提升到年老代的最大临界值. 默认值为 15.
-XX:G1HeapRegionSize=n region大小  默认值将根据 heap size 算出最优解;1M-32M
-XX:G1MixedGCCountTarget mixed回收执行次数,默认回收次数8。
-XX:G1HeapWastePercent,默认值是5%,就是说空出来的区域大于整个堆的5%,即使未达到回收次数,也会立即停止混合回收了。
如:默认回收次数是8次,但是可能到了4次,发现空闲Region大于整个堆的5%,就不会再进行后续回收了。可参考官网说明:https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html查看系统默认参数配置,如G1ReservePercent:  java -XX:+PrintFlagsFinal  | grep G1ReservePercentJVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64;
JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。

4.2 参数说明2

#堆内存最大最小值为4g,新生代内存2g
-Xms4g -Xmx4g -Xmn2g
#元空间128m,最大320m
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=320m
#开启远程debug
-Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n #使用G1垃圾收集器,在低延迟和高吞吐间寻找平衡,可以调整最大停止时间,设置新生代大小来提高吞吐量,让出cpu资源
-XX:+UseG1GC
#设置最大暂停时间,默认200ms
-XX:MaxGCPauseMillis=200
#指定Region大小,必须是2次幂
-XX:G1HeapRegionSize=2m
#反复执行混合回收8次,每次回收受MaxGCPauseMillis的影响可能一次性回收不了所有垃圾,增加次数才能回收的更彻底
-XX:G1MixedGCCountTarget=8
# 混合回收整理出来的空闲空间占heap的10时,结果老年代的回收,默认5
-XX:G1HeapWastePercent=10
#设置新生代大小,最大60%,默认5%
-XX:G1NewSizePercent=10 -XX:G1MaxNewSizePercent=50-XX:SurvivorRatio=8
#在控制台输出GC情况
-verbose:gc
#gc日志打印到执行日志文件
-Xloggc:./logs/job_execute_gc.log
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime
#可以生成更详细的Survivor空间占用日志
-XX:+PrintAdaptiveSizePolicy
#jdk 1.6开始,默认server模式下开启了这个参数,意为当jvm检测到程序在重复抛一个异常,在执行若干次后会将异常吞掉
-XX:-OmitStackTraceInFastThrow
-XX:-UseLargePages
#指定加载配置文件
--spring.config.location=classpath:/,classpath:/config/,file:./,file:./config/,file:/home/mall-job/conf/#---当前分布式任务调度采用jvm参数,-Xmn2g,-XX:MaxGCPauseMillis=400调整新生代内存大小,增大暂停时间提高吞吐量---------------------------
-Xms4g -Xmx4g -Xmn2g -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n -XX:+UseG1GC -XX:MaxGCPauseMillis=400 -XX:G1HeapRegionSize=2m -XX:G1MixedGCCountTarget=8 -XX:G1MixedGCCountTarget=8 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -Xloggc:/logs/execute/mall-job-execute-gc.log

5. 垃圾回收日志记录的垃圾收集原因

5.1 G1 Evacuation Pause

2022-05-17T02:59:17.637+0800: 34453.382: [GC pause (G1 Evacuation Pause) (young), 0.0521838 secs][Parallel Time: 48.1 ms, GC Workers: 10][GC Worker Start (ms): Min: 34453382.6, Avg: 34453382.8, Max: 34453383.0, Diff: 0.3][Ext Root Scanning (ms): Min: 0.4, Avg: 0.8, Max: 2.0, Diff: 1.6, Sum: 7.9][Update RS (ms): Min: 21.9, Avg: 22.9, Max: 23.4, Diff: 1.6, Sum: 229.2][Processed Buffers: Min: 43, Avg: 51.5, Max: 77, Diff: 34, Sum: 515][Scan RS (ms): Min: 17.4, Avg: 17.6, Max: 17.8, Diff: 0.4, Sum: 176.5][Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1][Object Copy (ms): Min: 5.9, Avg: 6.0, Max: 6.1, Diff: 0.2, Sum: 60.3][Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1][Termination Attempts: Min: 1, Avg: 14.1, Max: 21, Diff: 20, Sum: 141][GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.3, Diff: 0.3, Sum: 1.4][GC Worker Total (ms): Min: 47.3, Avg: 47.5, Max: 47.8, Diff: 0.5, Sum: 475.4][GC Worker End (ms): Min: 34453430.3, Avg: 34453430.4, Max: 34453430.5, Diff: 0.3][Code Root Fixup: 0.0 ms][Code Root Purge: 0.0 ms][Clear CT: 1.0 ms][Other: 3.1 ms][Choose CSet: 0.0 ms][Ref Proc: 0.8 ms][Ref Enq: 0.0 ms][Redirty Cards: 1.1 ms][Humongous Register: 0.1 ms][Humongous Reclaim: 0.0 ms][Free CSet: 0.8 ms][Eden: 2128.0M(2128.0M)->0.0B(2128.0M) Survivors: 6144.0K->6144.0K Heap: 3265.8M(4096.0M)->1138.3M(4096.0M)][Times: user=0.49 sys=0.00, real=0.05 secs]

5.2 to-space exhausted(空间耗尽)

2022-05-16T18:39:14.581+0800: 4450.326: [GC pause (G1 Evacuation Pause) (young) (to-space exhausted), 0.0626620 secs][Parallel Time: 24.5 ms, GC Workers: 10][GC Worker Start (ms): Min: 4450326.1, Avg: 4450326.1, Max: 4450326.2, Diff: 0.1][Ext Root Scanning (ms): Min: 0.9, Avg: 1.1, Max: 2.0, Diff: 1.1, Sum: 11.4][Update RS (ms): Min: 1.3, Avg: 1.9, Max: 2.1, Diff: 0.9, Sum: 19.2][Processed Buffers: Min: 16, Avg: 33.3, Max: 71, Diff: 55, Sum: 333][Scan RS (ms): Min: 0.1, Avg: 0.1, Max: 0.2, Diff: 0.1, Sum: 1.3][Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0][Object Copy (ms): Min: 20.6, Avg: 20.7, Max: 20.8, Diff: 0.2, Sum: 207.0][Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 1.3][Termination Attempts: Min: 1, Avg: 1.3, Max: 3, Diff: 2, Sum: 13][GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3][GC Worker Total (ms): Min: 24.0, Avg: 24.1, Max: 24.1, Diff: 0.1, Sum: 240.5][GC Worker End (ms): Min: 4450350.2, Avg: 4450350.2, Max: 4450350.2, Diff: 0.1][Code Root Fixup: 0.0 ms][Code Root Purge: 0.0 ms][Clear CT: 0.5 ms][Other: 37.6 ms][Evacuation Failure: 35.3 ms][Choose CSet: 0.0 ms][Ref Proc: 0.5 ms][Ref Enq: 0.0 ms][Redirty Cards: 0.6 ms][Humongous Register: 0.1 ms][Humongous Reclaim: 0.0 ms][Free CSet: 0.6 ms][Eden: 1618.0M(1618.0M)->0.0B(1620.0M) Survivors: 20.0M->18.0M Heap: 4075.5M(4096.0M)->2632.0M(4096.0M)][Times: user=0.47 sys=0.00, real=0.07 secs]

old区的使用速度超过了垃圾收集器的回收速度,考虑两种调优的思路。

通过调小-XX:InitiatingHeapOccupancyPercent=N这个参数,默认情况下该参数是45,让G1更早得启动混合式垃圾收集周期

增加每次混合式垃圾收集收集的Old分区数量,通过调整-XX:G1MixedGCCountTarget=N参数可以控制每个混合式周期中回收的Old分区数量,该参数的默认值是8

增加-XX:G1ReservePercent的大小,在G1中这个默认值是10%。

通过调整-XX:ConcGCThreads,增加用于垃圾收集的线程个数,代价是会多一些CPU的消耗;也就是会占用Java应用的CPU时间,从垃圾回收日志,可以看出是几个线程进行垃圾回收。

有时候转移失败是由于survivor分区中没有足够的空间容纳新晋升的对象,如果是这种情况,还可以考虑增加-XX:G1ReservePercent的大小,在G1中这个默认值是10%。

-XX:G1HeapRegionSize=4M,分区太小,容易引起碎片,并且容易出现回收效率低。

-XX:MaxTenuringThreshold=n:晋升到老年代的“年龄”阀值,默认值为 15。

-XX:G1MixedGCCountTarget:一次全局并发标记之后,后续最多执行的MixedGC次数。 默认值是8

5.3 to-space overflow(空间溢出)

增加-XX:G1ReservePercent。默认值是Java堆的10%。

5.4 Humongous Allocation

可以加大region的大小,设置-XX:G1HeapRegionSize=n。

6. 垃圾收集日志相关参数

6.1 -XX:+HeapDumpAfterFullGC 和 -XX:+HeapDumpOnOutOfMemoryError

在发生FGC和OOM的时候将当时的Java堆情况记录下来,用于事后分析。

6.2 日志记录参数

-Xms6144m -Xmx6144m -XX:+UseG1GC -XX:MaxGCPauseMillis=500
-Xloggc:/home/finance/Logs/xxx/xxx-gc.log
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=50M 

7. 参数配置案例

nohup java -Xms2048m -Xmx2048m -XX:+UseG
1GC -XX:G1ReservePercent=10 -XX:G1MixedGCCountTarget=8 -XX:InitiatingHeapOccup
ancyPercent=45 -XX:MaxMetaspaceSize=512m -XX:MaxTenuringThreshold=15 -XX:G1HeapR
egionSize=4m -XX:+HeapDumpAfterFullGC -XX:+HeapDumpOnOutOfMemoryError -XX:+Unloc
kExperimentalVMOptions -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=60 -XX:G1
MixedGCLiveThresholdPercent=50 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+P
rintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFi
leSize=50M -Xloggc:./gc.log -jar  server.jar  > server.log 2>&1 &

java g1垃圾收集器优化参考相关推荐

  1. 转:深入理解Java G1垃圾收集器

    本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么 ...

  2. 深入理解 Java G1 垃圾收集器--转

    原文地址:http://blog.jobbole.com/109170/?utm_source=hao.jobbole.com&utm_medium=relatedArticle 本文首先简单 ...

  3. 深入理解 Java G1 垃圾收集器

    本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么 ...

  4. 深入理解 Java G1 垃圾收集器GC调优

    本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么 ...

  5. java -g_【JVM】7、深入理解Java G1垃圾收集器

    本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么 ...

  6. java G1垃圾收集器

    Garbage-First(后文简称G1)收集器是当今收集器技术发展的最前沿成果,在Sun公司给出的JDK RoadMap里面,它被视作JDK 7的HotSpot VM 的一项重要进化特征.从JDK ...

  7. 深入解析G1垃圾收集器与性能优化

    本文详细介绍G1垃圾收集器的参数配置,如何进行性能调优, 以及怎样对GC性能进行分析和评估. 文章目录 0. G1简介 1. 垃圾回收阶段简介 2. 纯年轻代模式的垃圾收集 3. 混合模式的垃圾收集 ...

  8. JVM优化系列-JVM G1 垃圾收集器

    导语   G1回收器是在JDK1.7中正式使用的一种全新的垃圾回收器,它的目标是为了取代CMS回收器.G1回收器拥有独特的垃圾回收策略,和之前的任意的一种垃圾回收器都有所不同,但是从分代策略上来说依然 ...

  9. JVM性能调优实践:G1 垃圾收集器介绍篇

    前言 前面两篇主要整理了性能测试的主要观察指标信息:性能测试篇,以及JVM性能调优的工具:JVM篇.这一篇先简单总结一下GC的种类,然后侧重总结下G1(Garbage-First)垃圾收集器的分代,结 ...

最新文章

  1. java junit 运行_appium+java+junit demo运行
  2. 面向自动驾驶领域的3D点云目标检测方法汇总!(单模态+多模态/数据+代码)
  3. 职称计算机与二级计算机合并,职称计算机考试:excel按数据位置合并
  4. Altium Designer /DXP无网络铺铜:
  5. 说说在MVC开发中,遇到的错误及解决方法(本文章是我在实际开发中总结出来的,希望对您有帮助)...
  6. 计算机蠕虫是一个程序或程序系列,它采取截取口令并试图在系统中,计算机蠕虫病毒是一个程序或程序系列,它采取截取口令并试图在系统中做非法动作的方式直接攻击计算机。...
  7. 罗格斯的计算机科学,Rutgers的CS「罗格斯大学计算机科学系」
  8. 小黑框运行java_初探Java类加载机制
  9. java 数组 源码_Java数组转List的三种方式及对比
  10. java中io创建文件和读取文件
  11. 弱电工程数据中心机房现状定位优化
  12. abc物动量分析计算机视频,物动量ABC分类法
  13. html svg矩形添加文字,SVG 矩形
  14. 企业建站使用哪些主流的CMS系统?
  15. Jarvis OJ BASIC 公倍数
  16. python简易爬取喜马拉雅MP3
  17. 三分钟集成 TapTap 防沉迷 SDK(Unity 版)
  18. 入侵91网直到拿下服务器#并泄露150w+用户信息
  19. php memcached 实例,php memcached mysql开发详细实例
  20. linux 密码设置问题

热门文章

  1. 大数据排序方案---外排序介绍
  2. 国际嵌入式展会中国首秀,即将登陆上海!
  3. 在exsi虚拟主机中怎么安装win10或者win7
  4. OSPF协议之链路数据库同步
  5. 4个最常见的线下涨粉方式,没听过说明你out了!
  6. 10个有趣的 Python 高级脚本,建议收藏!
  7. 滑动窗口算法(Sliding Window Algorithm)
  8. python画叮当猫和大雄、皮卡丘
  9. C语言格式化输出(printf)
  10. python爬虫--URL部分加密破解