G1的mixed gc详细过程

G1的mixed gc详细过程

   G1会动态调整年轻代和老年代空间大小,为了达到接近预期的暂停时间;G1提供了两种GC模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。
   当达到IHOP阈值-XX:InitiatingHeapOccupancyPercent(老年代占整堆比,默认45%)时,便会触发并发标记周期。
   整个并发标记周期将由初始标记(Initial Mark)、根分区扫描(Root Region Scanning)、并发标记(Concurrent Marking)、重新标记(Remark)、清除(Cleanup)几个阶段组成。
   其中,初始标记(随年轻代收集一起活动)、重新标记、清除是STW的,

过程如下在这里插入图片描述

   初始标记(Initial Mark)

2021-11-05T14:39:40.189+0800: 16373.190: [GC pause (G1 Evacuation Pause) (young) (initial-mark), 0.0579957 secs]
   [Parallel Time: 44.5 ms, GC Workers: 8]
      [GC Worker Start (ms): Min: 16373191.1, Avg: 16373191.3, Max: 16373191.9, Diff: 0.7]
      [Ext Root Scanning (ms): Min: 0.3, Avg: 1.0, Max: 2.1, Diff: 1.8, Sum: 8.1]
      [Update RS (ms): Min: 6.6, Avg: 7.4, Max: 8.1, Diff: 1.5, Sum: 59.5]
         [Processed Buffers: Min: 12, Avg: 15.9, Max: 23, Diff: 11, Sum: 127]
      [Scan RS (ms): Min: 15.7, Avg: 16.1, Max: 16.4, Diff: 0.7, Sum: 128.6]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 18.7, Avg: 18.9, Max: 19.0, Diff: 0.3, Sum: 151.0]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Termination Attempts: Min: 1, Avg: 1.5, Max: 2, Diff: 1, Sum: 12]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.3, Diff: 0.3, Sum: 1.1]
      [GC Worker Total (ms): Min: 43.1, Avg: 43.5, Max: 43.8, Diff: 0.7, Sum: 348.4]
      [GC Worker End (ms): Min: 16373234.8, Avg: 16373234.9, Max: 16373235.0, Diff: 0.2]
   [Code Root Fixup: 0.1 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 1.4 ms]
   [Other: 12.0 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 7.5 ms]
      [Ref Enq: 0.4 ms]
      [Redirty Cards: 0.6 ms]
      [Humongous Register: 0.1 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 2.3 ms]
   [Eden: 378.0M(378.0M)->0.0B(545.0M) Survivors: 20.0M->22.0M Heap: 625.4M(2048.0M)->250.1M(2048.0M)]
[Times: user=0.36 sys=0.01, real=0.06 secs]

根分区扫描(Root Region Scanning)

2021-11-05T14:39:40.247+0800: 16373.249: [GC concurrent-root-region-scan-start]
2021-11-05T14:39:40.308+0800: 16373.310: [GC concurrent-root-region-scan-end, 0.0610685 secs]

并发标记(Concurrent Marking)

2021-11-05T14:39:40.308+0800: 16373.310: [GC concurrent-mark-start]
2021-11-05T14:39:40.533+0800: 16373.535: [GC concurrent-mark-end, 0.2253183 secs]

重新标记(Remark)

2021-11-05T14:39:40.534+0800: 16373.536: [GC remark 2021-11-05T14:39:40.534+0800: 16373.536: [Finalize Marking, 0.0005696 secs] 2021-11-05T14:39:40.535+0800: 16373.536: [GC ref-proc, 0.0045710 secs] 2021-11-05T14:39:40.539+0800: 16373.541: [Unloading, 0.0077477 secs], 0.0146888 secs]

清除(Cleanup)

2021-11-05T14:39:40.549+0800: 16373.551: [GC cleanup 253M->252M(2048M), 0.0061561 secs]
[Times: user=0.02 sys=0.01, real=0.00 secs]
2021-11-05T14:39:40.556+0800: 16373.558: [GC concurrent-cleanup-start]
2021-11-05T14:39:40.556+0800: 16373.558: [GC concurrent-cleanup-end, 0.0000344 secs]

   下面是整个mixed gc日志:看到初始标记(Initial Mark)、根分区扫描(Root Region Scanning)、并发标记(Concurrent Marking)、重新标记(Remark)、清除(Cleanup) 总耗时在0.4秒; 而一个yong gc耗时是在0.07秒;

命令:jstat -gcutil pid
在这里插入图片描述

得出结论

  1. Mixed GC是由Young GC触发的,或者说借机同时执行的,使用命令jstat -gcutil pid可以看出发生mixed gc后, 是在YGC, YGCT加次数和时间
  2. mixed gc耗时还是挺长的; 可以尝试适当的调高-XX:G1HeapWastePercent阈值,能够适当的降低Mixed GC的频率

自己做的一个实验:

条件:-Xmx2048m -Xms2048m -XX:G1HeapWastePercent=10 -XX:InitiatingHeapOccupancyPercent=20
结果:
  持续发送一天的数据, 观察opentsdb的old gc分区使用内存和整个堆的占比会一直在10%-30%之间徘徊, 不会一直增长,有效的回收

mixed gc

2021-11-05T15:14:48.654+0800: 18481.656: [GC pause (G1 Evacuation Pause) (young) (initial-mark), 0.0719531 secs]
   [Parallel Time: 55.8 ms, GC Workers: 8]
      [GC Worker Start (ms): Min: 18481656.6, Avg: 18481656.9, Max: 18481657.5, Diff: 1.0]
      [Ext Root Scanning (ms): Min: 0.7, Avg: 1.6, Max: 4.0, Diff: 3.2, Sum: 12.6]
      [Update RS (ms): Min: 7.5, Avg: 9.4, Max: 10.4, Diff: 2.9, Sum: 74.9]
         [Processed Buffers: Min: 10, Avg: 13.0, Max: 25, Diff: 15, Sum: 104]
      [Scan RS (ms): Min: 18.9, Avg: 19.2, Max: 19.5, Diff: 0.6, Sum: 154.0]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 24.6, Avg: 24.8, Max: 25.0, Diff: 0.5, Sum: 198.1]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Termination Attempts: Min: 1, Avg: 5.8, Max: 9, Diff: 8, Sum: 46]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.1, Sum: 0.8]
      [GC Worker Total (ms): Min: 54.5, Avg: 55.1, Max: 55.4, Diff: 0.9, Sum: 440.5]
      [GC Worker End (ms): Min: 18481711.9, Avg: 18481711.9, Max: 18481712.0, Diff: 0.1]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 1.1 ms]
   [Other: 15.1 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 11.5 ms]
      [Ref Enq: 0.4 ms]
      [Redirty Cards: 0.4 ms]
      [Humongous Register: 0.1 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 1.4 ms]
   [Eden: 451.0M(316.0M)->0.0B(1107.0M) Survivors: 19.0M->26.0M Heap: 732.3M(2048.0M)->287.5M(2048.0M)]
[Times: user=0.49 sys=0.00, real=0.07 secs]
2021-11-05T15:14:48.726+0800: 18481.728: [GC concurrent-root-region-scan-start]
2021-11-05T15:14:48.790+0800: 18481.791: [GC concurrent-root-region-scan-end, 0.0635930 secs]
2021-11-05T15:14:48.790+0800: 18481.791: [GC concurrent-mark-start]
2021-11-05T15:14:49.056+0800: 18482.057: [GC concurrent-mark-end, 0.2661284 secs]
2021-11-05T15:14:49.056+0800: 18482.058: [GC remark 2021-11-05T15:14:49.056+0800: 18482.058: [Finalize Marking, 0.0006772 secs] 2021-11-05T15:14:49.057+0800: 18482.059: [GC ref-proc, 0.0047694 secs] 2021-11-05T15:14:49.062+0800: 18482.064: [Unloading, 0.0065857 secs], 0.0138728 secs]
[Times: user=0.06 sys=0.01, real=0.02 secs]
2021-11-05T15:14:49.071+0800: 18482.073: [GC cleanup 293M->292M(2048M), 0.0052534 secs]
[Times: user=0.03 sys=0.00, real=0.00 secs]
2021-11-05T15:14:49.076+0800: 18482.078: [GC concurrent-cleanup-start]
2021-11-05T15:14:49.076+0800: 18482.078: [GC concurrent-cleanup-end, 0.0000441 secs]

young gc

021-11-05T15:20:50.084+0800: 18843.086: [GC pause (G1 Evacuation Pause) (young), 0.0714720 secs]
   [Parallel Time: 60.6 ms, GC Workers: 8]
      [GC Worker Start (ms): Min: 18843087.2, Avg: 18843088.2, Max: 18843092.1, Diff: 4.9]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.3, Max: 0.7, Diff: 0.7, Sum: 2.4]
      [Update RS (ms): Min: 9.2, Avg: 13.0, Max: 14.2, Diff: 5.0, Sum: 104.0]
         [Processed Buffers: Min: 13, Avg: 18.9, Max: 36, Diff: 23, Sum: 151]
      [Scan RS (ms): Min: 16.5, Avg: 17.0, Max: 17.2, Diff: 0.7, Sum: 136.1]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [Object Copy (ms): Min: 29.0, Avg: 29.0, Max: 29.1, Diff: 0.1, Sum: 232.1]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 8]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.1, Sum: 0.8]
      [GC Worker Total (ms): Min: 55.5, Avg: 59.4, Max: 60.4, Diff: 4.9, Sum: 475.5]
      [GC Worker End (ms): Min: 18843147.5, Avg: 18843147.6, Max: 18843147.7, Diff: 0.2]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.7 ms]
   [Other: 10.2 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 4.5 ms]
      [Ref Enq: 0.3 ms]
      [Redirty Cards: 0.3 ms]
      [Humongous Register: 0.5 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 3.7 ms]
   [Eden: 1222.0M(1222.0M)->0.0B(1208.0M) Survivors: 6144.0K->20.0M Heap: 1476.8M(2048.0M)->268.7M(2048.0M)]
[Times: user=0.50 sys=0.00, real=0.07 secs]

年轻代收集和混合收集周期,是G1回收空间的主要活动

    当应用运行开始时,堆内存可用空间还比较大,只会在年轻代满时,触发年轻代收集;随着老年代内存增长,当到达IHOP阈值-XX:InitiatingHeapOccupancyPercent(老年代占整堆比,默认45%)时,G1开始着手准备收集老年代空间。
    首先经历并发标记周期,识别出高收益的老年代分区,前文已述。但随后G1并不会马上开始一次混合收集,而是让应用线程先运行一段时间,等待触发一次年轻代收集。在这次STW中,G1将保准整理混合收集周期。接着再次让应用线程运行,当接下来的几次年轻代收集时,将会有老年代分区加入到CSet中,即触发混合收集,这些连续多次的混合收集称为混合收集周期(Mixed Collection Cycle)。

mixed gc 优化的参数

-XX:MaxGCPauseMillis

   暂停时间,默认值200ms。这是一个软性目标,G1会尽量达成,如果达不成,会逐渐做自我调整。
   对于Young GC来说,会逐渐减少Eden区个数,减少Eden空间那么Young GC的处理时间就会相应减少。对于Mixed GC,G1会调整每次Choose Cset的比例,默认最大值是10%,当然每次选择的Cset少了,所要经历的Mixed GC的次数会相应增加。
   减少Eden的总空间时,就会更加频繁的触发Young GC,也就是会加快Mixed GC的执行频率,因为Mixed GC是由Young GC触发的,或者说借机同时执行的。 频繁GC会对对应用的吞吐量造成影响,每次Mixed GC回收时间太短,回收的垃圾量太少,可能最后GC的垃圾清理速度赶不上应用产生的速度,那么可能会造成串行的Full GC,这是要极力避免的。所以暂停时间肯定不是设置的越小越好,当然也不能设置的偏大,转而指望G1自己会尽快的处理,这样可能会导致一次全部并发标记后触发的Mixed GC次数变少,但每次的时间变长,STW时间变长,对应用的影响更加明显。

-XX:G1HeapRegionSize

   Region大小,若未指定则默认最多生成2048块,每块的大小需要为2的幂次方,如1,2,4,8,16,32,最大值为32M。Region的大小主要是关系到Humongous Object的判定,当一个对象超过Region大小的一半时,则为巨型对象,那么其会至少独占一个Region,如果一个放不下,会占用连续的多个Region。当一个Humongous Region放入了一个巨型对象,可能还有不少剩余空间,但是不能用于存放其他对象,这些空间就浪费了。所以如果应用里有很多大小差不多的巨型对象,可以适当调整Region的大小,尽量让他们以普通对象的形式分配,合理利用Region空间。

-XX:InitiatingHeapOccupancyPercent

   通过-XX:InitiatingHeapOccupancyPercent指定触发全局并发标记的老年代使用占比,默认值45%,也就是老年代占堆的比例超过45%。如果Mixed GC周期结束后老年代使用率还是超过45%,那么会再次触发全局并发标记过程,这样就会导致频繁的老年代GC,影响应用吞吐量。同时老年代空间不大,Mixed GC回收的空间肯定是偏少的。可以适当调高值,当然如果此值太高,很容易导致年轻代晋升失败而触发Full GC,所以需要多次调整测试。

-XX:G1HeapWastePercent

   通过-XX:G1HeapWastePercent指定触发Mixed GC的堆垃圾占比,默认值5%,也就是在全局标记结束后能够统计出所有Cset内可被回收的垃圾占整对的比例值,如果超过5%,那么就会触发之后的多轮Mixed GC,如果不超过,那么会在之后的某次Young GC中重新执行全局并发标记。可以尝试适当的调高此阈值,能够适当的降低Mixed GC的频率。

g1参数调优(jvm分配的内存较大的情况)

-Xmx8192m
-Xms8192m
-XX:+UseG1GC
-XX:+ExitOnOutOfMemoryError
-XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions
-XX:G1MixedGCLiveThresholdPercent=85
-XX:G1MaxNewSizePercent=45
-XX:G1HeapWastePercent=10
-XX:InitiatingHeapOccupancyPercent=30
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/data/tmp/gc.log

参考:https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
G1GC是一种垃圾回收器,它是Java虚拟机中的一部分,用于管理内存中的垃圾对象。G1GC的全称是Garbage-First,它采用了一种独特的垃圾回收策略,可以在多线程同时工作的情况下进行垃圾回收,并且可以与应用程序交替执行,不会完全阻塞应用程序。 G1GC的主要特点包括: - 分代回收:G1GC将堆内存划分为多个区域,每个区域称为一个分代。它会根据垃圾对象的分布情况,优先回收垃圾最多的分代。 - 并发回收:G1GC可以在应用程序运行的同时进行垃圾回收,减少了停顿时间。 - 区域化回收:G1GC将堆内存划分为多个区域,每个区域都可以独立进行垃圾回收,提高了回收效率。 - 可预测的停顿时间:G1GC通过控制每次垃圾回收的时间,可以实现可预测的停顿时间,避免了长时间的停顿对应用程序性能的影响。 要在Tomcat中启用G1GC,可以按照以下步骤进行配置: 1. 打开Tomcat的启动脚本文件(如catalina.sh或catalina.bat)。 2. 在JAVA_OPTS环境变量中添加以下参数: ``` -XX:+UseG1GC -XX:MaxGCPauseMillis=<最大停顿时间> -XX:G1HeapRegionSize=<堆区域大小> ``` 其中,`<最大停顿时间>`是期望的最大停顿时间(以毫秒为单位),`<堆区域大小>`是每个堆区域的大小(以字节为单位)。 3. 保存并关闭启动脚本文件。 4. 重新启动Tomcat。 请注意,G1GC的配置参数可以根据具体的应用程序需求进行调整。建议根据实际情况进行性能测试和调优。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里风雪

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值