G1垃圾回收器

目录

  • 基础知识
  • 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默认年轻代老年代占比1/3,不配置会动态变


    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份均分。G1垃圾回收器默认情况下年轻代占比为5%,在系统运行中,jvm也会不断调整,增加年轻代的区域,但是默认不超过60%
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,最终是反射导致的


参考文章

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容