目录
- 基础知识
- 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垃圾收集器种类
- 新生代
- Serial (第一代)
- PraNew (第二代)
- Parallel Scavenge (第三代)
- G1收集器(第四代)
- 老年代
- Serial Old (第一代)
- Parallel Old (第二代)
- CMS (第三代)
- 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区
- 回收过程
- 根扫描,跟CMS类似,Stop the world,扫描GC Roots对象。
- 处理Dirty card,更新RSet.
- 扫描RSet, 扫描RSet中所有old区对扫描到的young区或者survivor去的引用。
- 拷贝扫描出的存活的对象到survivor2/old区
- 处理引用队列,软引用,弱引用,虚引用
Old GC /并发标记周期
- 主要完成了垃圾定位的工作,定位出了哪些分区是垃圾最多的,因为整堆一般比较大,所以这个周期应该会比较长,中间可能会被多次 stop-the-world 的 Young GC 打断。
- 初始标记:stop-the-world,它伴随着一次普通的 Young GC 发生,然后对 Survivor 区(root region)进行标记,因为该区可能存在对老年代的引用。因为 Young GC 是需要 stop-the-world 的,所以并发周期直接重用这个阶段,虽然会增加 CPU 开销,但是停顿时间只是增加了一小部分。
- 并发标记:寻找整个堆的存活对象,该阶段可以被 Young GC 中断
- 重新标记:stop-the-world,完成最后的存活对象标记
- 清理:清理阶段真正回收的内存很少。
- 在分配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的因素
- concurrent mode failure:并发模式失败,CMS 收集器也有同样的概念。G1 并发标记期间,如果在标记结束前,老年代被填满,G1 会放弃标记。这个时候说明
一. 堆需要增加了
二. 或者需要调整并发周期,如增加并发标记的线程数量,让并发标记尽快结束
三. 或者就是更早地进行并发周期,默认是整堆内存的 45% 被占用就开始进行并发周期。 - 晋升失败:并发周期结束后,是混合垃圾回收周期,伴随着年轻代垃圾收集,进行清理老年代空间,如果这个时候清理的速度小于消耗的速度,导致老年代不够用,那么会发生晋升失败。说明
一. 混合垃圾回收需要更迅速完成垃圾收集,也就是说在混合回收阶段,每次年轻代的收集应该处理更多的老年代已标记区块。 - 疏散失败:年轻代垃圾收集的时候,如果 Survivor 和 Old 区没有足够的空间容纳所有的存活对象。这种情况肯定是非常致命的,因为基本上已经没有多少空间可以用了,这个时候会触发 Full GC 也是很合理的。说明:
一. 最简单的就是增加堆大小 - 大对象分配失败,我们应该尽可能地不创建大对象,尤其是大于一个区块大小的那种对象。
- MetaSpace满了时
- 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]
- 具体字段含义【译】深入理解G1的GC日志(一)这篇文章分析的比较透彻
线上参数
-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数
网友评论