美文网首页
G1垃圾回收器

G1垃圾回收器

作者: 后来丶_a24d | 来源:发表于2020-03-30 16:52 被阅读0次

    目录

    • 基础知识
    • G1回收流程
    • GC日志解析
    • 线上参数
    • 调优案例

    基础知识

    目的
    • G1 的主要关注点在于达到可控的停顿时间,在这个基础上尽可能提高吞吐量
    • G1 没有 CMS回收器 的碎片化问题(或者说不那么严重),同时提供了更加可控的停顿时间
    • 如果你的应用使用了较大的堆,而且还要求有较低的垃圾收集停顿时间(如 0.5 秒),那么 G1 非常适合
    发展历史
    • Serial(串行)收集器: Serial收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。
    • Parallel收集器 : 相比Serial收集器,Parallel最主要的优势在于使用多线程去完成垃圾清理工作,这样可以充分利用多核的特性,大幅降低gc时间。
    • CMS收集器: 在Minor GC时会暂停所有的应用线程,并以多线程的方式进行垃圾回收。在Full GC时不再暂停应用线程,而是使用若干个后台线程定期的对老年代空间进行扫描,及时回收其中不再使用的对象。
    • G1收集器(或者垃圾优先收集器)的设计初衷是为了尽量缩短处理超大堆(大于4GB)时产生的停顿
    G1对比CMS回收器总览
    • CMS分代收集器将整个堆分为年轻代、老年代和永久代,每个代的空间是确定的


      CMS.png
    • 而 G1 将整个堆划分为一个个大小相等的小块(每一块称为一个 region),每一块的内存是连续的。和分代算法一样,G1 中每个块也会充当 Eden、Survivor、Old 三种角色,但是它们不是固定的,这使得内存使用更加地灵活, 当然还有H(Humongous, 表示这些Region存储的是巨大对象(humongous object,H-obj,H-obj直接分配到了old gen),即大小大于等于region一半的对象)图中未展示


      G1.png
    • G1堆内存中一个区域(Region)的大小可以通过-XX:G1HeapRegionSize参数指定,大小区间最小1M、最大32M,总之是2的幂次方。默认把堆内存按照2048份均分。
    JVM垃圾收集器种类
    • 新生代
    1. Serial (第一代)
    2. PraNew (第二代)
    3. Parallel Scavenge (第三代)
    4. G1收集器(第四代)
    • 老年代
    1. Serial Old (第一代)
    2. Parallel Old (第二代)
    3. CMS (第三代)
    4. G1收集器 (第四代)

    G1回收流程

    基础
    • Remembered Sets:每个区块都有一个 RSet,用于记录进入该区块的对象引用(如区块 A 中的对象引用了区块 B,区块 B 的 Rset 需要记录这个信息),它用于实现收集过程的并行化以及使得区块能进行独立收集。总体上 Remembered Sets 消耗的内存小于 5%。
    • Collection Sets:将要被回收的区块集合。GC 时,在这些区块中的对象会被复制到其他区块中,总体上 Collection Sets 消耗的内存小于 1%。
    年轻代YoungGC收集
    • 当所有eden region使用达到最大阀值并且无法申请足够内存时,会触发一次YoungGC。每次younggc会回收所有Eden以及Survivor区,并且将存活对象复制到Old区以及另一部分的Survivor区
    • 回收过程
    1. 根扫描,跟CMS类似,Stop the world,扫描GC Roots对象。
    2. 处理Dirty card,更新RSet.
    3. 扫描RSet, 扫描RSet中所有old区对扫描到的young区或者survivor去的引用。
    4. 拷贝扫描出的存活的对象到survivor2/old区
    5. 处理引用队列,软引用,弱引用,虚引用
    Old GC /并发标记周期
    • 主要完成了垃圾定位的工作,定位出了哪些分区是垃圾最多的,因为整堆一般比较大,所以这个周期应该会比较长,中间可能会被多次 stop-the-world 的 Young GC 打断。
    1. 初始标记:stop-the-world,它伴随着一次普通的 Young GC 发生,然后对 Survivor 区(root region)进行标记,因为该区可能存在对老年代的引用。因为 Young GC 是需要 stop-the-world 的,所以并发周期直接重用这个阶段,虽然会增加 CPU 开销,但是停顿时间只是增加了一小部分。
    2. 并发标记:寻找整个堆的存活对象,该阶段可以被 Young GC 中断
    3. 重新标记:stop-the-world,完成最后的存活对象标记
    4. 清理:清理阶段真正回收的内存很少。
    • 在分配H-obj之前先检查是否超过 initiating heap occupancy percent和the marking threshold, 如果超过的话,就启动global concurrent marking,为的是提早回收,
    mixed混合GC
    • 并发周期结束后是混合垃圾回收周期,不仅进行年轻代垃圾收集,而且回收之前标记出来的老年代的垃圾最多的部分区块。混合垃圾回收周期会持续进行,直到几乎所有的被标记出来的分区(垃圾占比大的分区)都得到回收,然后恢复到常规的年轻代垃圾收集,最终再次启动并发周期。
    • 当越来越多的对象晋升到老年代old region时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即mixed gc,该算法并不是一个old gc,除了回收整个young region,还会回收一部分的old region。
    Full GC
    • G1没有fullGC概念,需要fullGC时,调用serialOldGC进行全堆扫描, 尽量避免
    • 导致full gc的因素
    1. concurrent mode failure:并发模式失败,CMS 收集器也有同样的概念。G1 并发标记期间,如果在标记结束前,老年代被填满,G1 会放弃标记。这个时候说明
      一. 堆需要增加了
      二. 或者需要调整并发周期,如增加并发标记的线程数量,让并发标记尽快结束
      三. 或者就是更早地进行并发周期,默认是整堆内存的 45% 被占用就开始进行并发周期。
    2. 晋升失败:并发周期结束后,是混合垃圾回收周期,伴随着年轻代垃圾收集,进行清理老年代空间,如果这个时候清理的速度小于消耗的速度,导致老年代不够用,那么会发生晋升失败。说明
      一. 混合垃圾回收需要更迅速完成垃圾收集,也就是说在混合回收阶段,每次年轻代的收集应该处理更多的老年代已标记区块。
    3. 疏散失败:年轻代垃圾收集的时候,如果 Survivor 和 Old 区没有足够的空间容纳所有的存活对象。这种情况肯定是非常致命的,因为基本上已经没有多少空间可以用了,这个时候会触发 Full GC 也是很合理的。说明:
      一. 最简单的就是增加堆大小
    4. 大对象分配失败,我们应该尽可能地不创建大对象,尤其是大于一个区块大小的那种对象。
    5. MetaSpace满了时
    6. System.gc()也有可能

    GC日志解析

    • 线上日志
    
    2020-04-01T02:22:37.259+0800: 41886.299: [GC pause (G1 Evacuation Pause) (young), 0.0511506 secs]
       [Parallel Time: 49.6 ms, GC Workers: 2]
          [GC Worker Start (ms): Min: 41886299.2, Avg: 41886299.2, Max: 41886299.2, Diff: 0.0]
          [Ext Root Scanning (ms): Min: 2.6, Avg: 2.6, Max: 2.6, Diff: 0.0, Sum: 5.3]
          [Update RS (ms): Min: 1.4, Avg: 1.5, Max: 1.5, Diff: 0.0, Sum: 2.9]
             [Processed Buffers: Min: 27, Avg: 27.5, Max: 28, Diff: 1, Sum: 55]
          [Scan RS (ms): Min: 0.1, Avg: 0.1, Max: 0.1, Diff: 0.0, Sum: 0.1]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [Object Copy (ms): Min: 45.3, Avg: 45.3, Max: 45.3, Diff: 0.0, Sum: 90.6]
          [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: 2]
          [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [GC Worker Total (ms): Min: 49.5, Avg: 49.5, Max: 49.5, Diff: 0.0, Sum: 99.0]
          [GC Worker End (ms): Min: 41886348.7, Avg: 41886348.7, Max: 41886348.7, Diff: 0.0]
       [Code Root Fixup: 0.0 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 0.1 ms]
       [Other: 1.5 ms]
          [Choose CSet: 0.0 ms]
          [Ref Proc: 0.1 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.2 ms]
          [Humongous Register: 0.2 ms]
          [Humongous Reclaim: 0.2 ms]
          [Free CSet: 0.3 ms]
       [Eden: 119.0M(119.0M)->0.0B(1421.0M) Survivors: 34.0M->2048.0K Heap: 1431.1M(3072.0M)->1314.9M(3072.0M)]
     [Times: user=0.10 sys=0.00, real=0.05 secs] 
    2020-04-01T02:23:15.724+0800: 41924.764: [GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0792630 secs]
       [Parallel Time: 77.2 ms, GC Workers: 2]
          [GC Worker Start (ms): Min: 41924764.6, Avg: 41924764.7, Max: 41924764.7, Diff: 0.0]
          [Ext Root Scanning (ms): Min: 3.7, Avg: 3.9, Max: 4.1, Diff: 0.3, Sum: 7.8]
          [Update RS (ms): Min: 43.2, Avg: 43.2, Max: 43.3, Diff: 0.1, Sum: 86.5]
             [Processed Buffers: Min: 253, Avg: 266.5, Max: 280, Diff: 27, Sum: 533]
          [Scan RS (ms): Min: 0.2, Avg: 0.2, Max: 0.2, Diff: 0.0, Sum: 0.4]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [Object Copy (ms): Min: 29.6, Avg: 29.7, Max: 29.9, Diff: 0.3, Sum: 59.4]
          [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: 2]
          [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [GC Worker Total (ms): Min: 77.0, Avg: 77.1, Max: 77.1, Diff: 0.0, Sum: 154.1]
          [GC Worker End (ms): Min: 41924841.7, Avg: 41924841.7, Max: 41924841.7, Diff: 0.0]
       [Code Root Fixup: 0.0 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 0.2 ms]
       [Other: 1.8 ms]
          [Choose CSet: 0.0 ms]
          [Ref Proc: 0.1 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.0 ms]
          [Humongous Register: 0.1 ms]
          [Humongous Reclaim: 0.2 ms]
          [Free CSet: 0.4 ms]
       [Eden: 565.0M(1421.0M)->0.0B(234.0M) Survivors: 2048.0K->26.0M Heap: 1918.6M(3072.0M)->1342.0M(3072.0M)]
     [Times: user=0.16 sys=0.00, real=0.08 secs] 
    2020-04-01T02:23:15.804+0800: 41924.843: [GC concurrent-root-region-scan-start]
    2020-04-01T02:23:15.823+0800: 41924.863: [GC concurrent-root-region-scan-end, 0.0195871 secs]
    2020-04-01T02:23:15.823+0800: 41924.863: [GC concurrent-mark-start]
    2020-04-01T02:23:16.076+0800: 41925.116: [GC concurrent-mark-end, 0.2529475 secs]
    2020-04-01T02:23:16.077+0800: 41925.116: [GC remark 2020-04-01T02:23:16.077+0800: 41925.116: [Finalize Marking, 0.0002514 secs] 2020-04-01T02:23:16.077+0800: 41925.117: [GC ref-proc, 0.0065589 secs] 2020-04-01T02:23:16.083+0800: 41925.123: [Unloading, 0.0521240 secs], 0.0613578 secs]
     [Times: user=0.09 sys=0.02, real=0.06 secs] 
    2020-04-01T02:23:16.139+0800: 41925.178: [GC cleanup 1413M->600M(3072M), 0.0063161 secs]
     [Times: user=0.01 sys=0.00, real=0.00 secs] 
    2020-04-01T02:23:16.145+0800: 41925.185: [GC concurrent-cleanup-start]
    2020-04-01T02:23:16.147+0800: 41925.187: [GC concurrent-cleanup-end, 0.0020016 secs]
    2020-04-01T02:23:33.263+0800: 41942.303: [GC pause (G1 Evacuation Pause) (young), 0.0364350 secs]
       [Parallel Time: 35.0 ms, GC Workers: 2]
          [GC Worker Start (ms): Min: 41942303.5, Avg: 41942303.5, Max: 41942303.5, Diff: 0.0]
          [Ext Root Scanning (ms): Min: 2.3, Avg: 2.4, Max: 2.4, Diff: 0.1, Sum: 4.7]
          [Update RS (ms): Min: 10.3, Avg: 10.3, Max: 10.3, Diff: 0.0, Sum: 20.7]
             [Processed Buffers: Min: 139, Avg: 147.5, Max: 156, Diff: 17, Sum: 295]
          [Scan RS (ms): Min: 0.1, Avg: 0.1, Max: 0.1, Diff: 0.0, Sum: 0.2]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [Object Copy (ms): Min: 22.0, Avg: 22.1, Max: 22.1, Diff: 0.1, Sum: 44.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: 2]
          [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [GC Worker Total (ms): Min: 34.9, Avg: 34.9, Max: 34.9, Diff: 0.0, Sum: 69.7]
          [GC Worker End (ms): Min: 41942338.3, Avg: 41942338.3, Max: 41942338.3, Diff: 0.0]
       [Code Root Fixup: 0.0 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 0.1 ms]
       [Other: 1.3 ms]
          [Choose CSet: 0.0 ms]
          [Ref Proc: 0.1 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.1 ms]
          [Humongous Register: 0.1 ms]
          [Humongous Reclaim: 0.2 ms]
          [Free CSet: 0.2 ms]
       [Eden: 234.0M(234.0M)->0.0B(143.0M) Survivors: 26.0M->10.0M Heap: 792.7M(3072.0M)->520.3M(3072.0M)]
     [Times: user=0.07 sys=0.00, real=0.04 secs] 
    2020-04-01T02:23:46.011+0800: 41955.051: [GC pause (G1 Evacuation Pause) (mixed), 0.0347943 secs]
       [Parallel Time: 33.3 ms, GC Workers: 2]
          [GC Worker Start (ms): Min: 41955051.1, Avg: 41955051.1, Max: 41955051.1, Diff: 0.0]
          [Ext Root Scanning (ms): Min: 2.3, Avg: 2.3, Max: 2.3, Diff: 0.0, Sum: 4.6]
          [Update RS (ms): Min: 14.4, Avg: 14.5, Max: 14.5, Diff: 0.0, Sum: 28.9]
             [Processed Buffers: Min: 49, Avg: 66.0, Max: 83, Diff: 34, Sum: 132]
          [Scan RS (ms): Min: 0.9, Avg: 1.0, Max: 1.1, Diff: 0.1, Sum: 2.0]
          [Code Root Scanning (ms): Min: 0.2, Avg: 0.3, Max: 0.4, Diff: 0.1, Sum: 0.6]
          [Object Copy (ms): Min: 15.2, Avg: 15.2, Max: 15.2, Diff: 0.0, Sum: 30.4]
          [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: 2]
          [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [GC Worker Total (ms): Min: 33.3, Avg: 33.3, Max: 33.3, Diff: 0.0, Sum: 66.6]
          [GC Worker End (ms): Min: 41955084.4, Avg: 41955084.4, Max: 41955084.4, Diff: 0.0]
       [Code Root Fixup: 0.0 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 0.2 ms]
       [Other: 1.3 ms]
          [Choose CSet: 0.1 ms]
          [Ref Proc: 0.1 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.1 ms]
          [Humongous Register: 0.1 ms]
          [Humongous Reclaim: 0.1 ms]
          [Free CSet: 0.4 ms]
       [Eden: 143.0M(143.0M)->0.0B(142.0M) Survivors: 10.0M->11.0M Heap: 663.3M(3072.0M)->446.8M(3072.0M)]
     [Times: user=0.06 sys=0.00, real=0.04 secs] 
    2020-04-01T02:23:58.566+0800: 41967.606: [GC pause (G1 Evacuation Pause) (mixed), 0.0273826 secs]
       [Parallel Time: 25.9 ms, GC Workers: 2]
          [GC Worker Start (ms): Min: 41967606.0, Avg: 41967606.0, Max: 41967606.0, Diff: 0.0]
          [Ext Root Scanning (ms): Min: 2.3, Avg: 2.3, Max: 2.3, Diff: 0.0, Sum: 4.6]
          [Update RS (ms): Min: 8.3, Avg: 8.3, Max: 8.3, Diff: 0.0, Sum: 16.5]
             [Processed Buffers: Min: 53, Avg: 57.0, Max: 61, Diff: 8, Sum: 114]
          [Scan RS (ms): Min: 1.5, Avg: 1.7, Max: 1.8, Diff: 0.3, Sum: 3.3]
          [Code Root Scanning (ms): Min: 0.1, Avg: 0.3, Max: 0.4, Diff: 0.3, Sum: 0.6]
          [Object Copy (ms): Min: 13.4, Avg: 13.4, Max: 13.4, Diff: 0.0, Sum: 26.7]
          [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: 2]
          [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
          [GC Worker Total (ms): Min: 25.9, Avg: 25.9, Max: 25.9, Diff: 0.0, Sum: 51.8]
          [GC Worker End (ms): Min: 41967631.8, Avg: 41967631.8, Max: 41967631.8, Diff: 0.0]
       [Code Root Fixup: 0.0 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 0.2 ms]
       [Other: 1.2 ms]
          [Choose CSet: 0.1 ms]
          [Ref Proc: 0.1 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.1 ms]
          [Humongous Register: 0.1 ms]
          [Humongous Reclaim: 0.1 ms]
          [Free CSet: 0.3 ms]
       [Eden: 142.0M(142.0M)->0.0B(142.0M) Survivors: 11.0M->11.0M Heap: 588.8M(3072.0M)->391.3M(3072.0M)]
     [Times: user=0.05 sys=0.01, real=0.02 secs] 
    2020-04-01T02:24:11.056+0800: 41980.096: [GC pause (G1 Evacuation Pause) (mixed), 0.0271698 secs]
       [Parallel Time: 25.9 ms, GC Workers: 2]
          [GC Worker Start (ms): Min: 41980095.8, Avg: 41980095.8, Max: 41980095.8, Diff: 0.0]
          [Ext Root Scanning (ms): Min: 2.3, Avg: 2.3, Max: 2.3, Diff: 0.0, Sum: 4.7]
          [Update RS (ms): Min: 8.8, Avg: 8.9, Max: 9.0, Diff: 0.2, Sum: 17.8]
             [Processed Buffers: Min: 53, Avg: 55.5, Max: 58, Diff: 5, Sum: 111]
          [Scan RS (ms): Min: 0.4, Avg: 0.5, Max: 0.5, Diff: 0.1, Sum: 0.9]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
          [Object Copy (ms): Min: 14.1, Avg: 14.1, Max: 14.2, Diff: 0.1, Sum: 28.3]
          [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: 2]
          [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
          [GC Worker Total (ms): Min: 25.9, Avg: 25.9, Max: 25.9, Diff: 0.0, Sum: 51.8]
          [GC Worker End (ms): Min: 41980121.7, Avg: 41980121.7, Max: 41980121.7, Diff: 0.0]
       [Code Root Fixup: 0.0 ms]
       [Code Root Purge: 0.0 ms]
       [Clear CT: 0.1 ms]
       [Other: 1.1 ms]
          [Choose CSet: 0.0 ms]
          [Ref Proc: 0.1 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.1 ms]
          [Humongous Register: 0.1 ms]
          [Humongous Reclaim: 0.1 ms]
          [Free CSet: 0.2 ms]
       [Eden: 142.0M(142.0M)->0.0B(1841.0M) Survivors: 11.0M->2048.0K Heap: 534.3M(3072.0M)->383.8M(3072.0M)]
     [Times: user=0.05 sys=0.00, real=0.02 secs] 
     
     
    
    

    线上参数

     -Xss256k 栈大小
     -XX:MaxGCPauseMillis=200 GC预期最大停顿时间,JVM会尽可能满足这个目标,太小每次收集的数据就小
     -XX:+UseG1GC 使用G1 GC
     -XX:-OmitStackTraceInFastThrow 堆栈异常快速抛出
     -XX:CICompilerCount=2 编译时的编译器线程数
     -Xmx3072m 服务器是4g 最大堆 调整优化过
     -Xms3072m 最小堆 调整优化过
     -XX:MetaspaceSize=256m 元数据空间大小,调整优化过
     -XX:MaxMetaspaceSize=256m 最大元数据空间大小 调整优化过
     -XX:MinMetaspaceFreeRatio=0 空闲堆空间的最小百分比,HeapFreeRatio < MinHeapFreeRatio,则需要进行堆扩容,扩容的时机应该在每次垃圾回收之后
     -XX:MaxMetaspaceFreeRatio=100 空闲堆空间的最大百分比,如果HeapFreeRatio > MaxHeapFreeRatio,则需要进行堆缩容
     -XX:+PreserveFramePointer 显示完整的stack,优化过
     -XX:+PrintGC 打印日志
     -XX:+PrintGCDetails 打印日志
     -XX:+PrintGCDateStamps 打印日志
     -XX:+HeapDumpOnOutOfMemoryError oom报错
     -XX:ParallelGCThreads=2 并行配置GC线程数,与cpu核数相同
     -XX:ConcGCThreads=2 并发收集时线程数与cpu核数相同
     -XX:+PrintAdaptiveSizePolicy 分析优化gc策略,排查问题好帮手
    

    调优案例

    案例1
    • 每隔一两分钟就会Full GC, 从GC日志看,有频繁的大对象分配,GC cleanup 没有回收掉一点内存,说明老年代的对象都是可达
    GC pause (G1 Humongous Allocation)
    
    • jmap -histo:live pid查看String对象贼大
    • 使用MAT发现EvictingQueue对象非常多,而EvictingQueue中大量持有String对象。EvictingQueue在使用时已经设置了长度为100,但是在多线程环境下add会超过100.add源码
     public boolean add(E e) {
            checkNotNull(e);
            if (maxSize == 0) {
                return true;
            }
            if (size() == maxSize) {
                delegate.remove();
            }
            delegate.add(e);
            return true;
        }
    
    • 线程1和线程2同时进入add方法,判断size() == maxSize均为false,都执行了delegate.add方法并且都成功了,此时size()=101。那么在线程3执行add时,size() == maxSize仍为false,所以就会一直累加元素,直到OOM。size() >= maxSize避免击穿.

    案例2

    • full gc频繁,查看日志, 看了下生产Metadata 可能是mateSpace 空间不够导致OOM
    Full GC (Metadata GC Threshold)
    
    • 看了下生产jvm参数配置Metadata 过小导致的,增大之后问题解决。

    案例3

    • 服务器卡顿,打开-XX:+PrintAdaptiveSizePolicy查看日志发现
    predicted time is too high
    
    • 这说明设置的预期停顿时间内无法做到扫描很多区域。后面几次只是扫描了几个region就结束了,如果这些region都是昂贵的,自然需要很长的时间进行mixed gc
    • 解决的方案有:放宽预期停顿时间,降低-XX:G1OldCSetRegionThresholdPercent比例以降低预期时间,增加-XX:G1MixedGCCountTarget,减少每轮需要回收的region数

    案例4 元数据空间引起的fullgc,最终是反射导致的


    参考文章

    相关文章

      网友评论

          本文标题:G1垃圾回收器

          本文链接:https://www.haomeiwen.com/subject/yrivuhtx.html