Java性能-理解G1 垃圾回收器

垃圾回收算法

理解G1 垃圾回收器

G1是在堆内离散的区域进行,各个区域(默认2048个),可能是老年代也可能是新生代并且区域不连续
实际上回收一个区域的时候仍然需要停止应用程序线程,但G1可以专注于回收那些大部分是垃圾的区域
清空大部分垃圾的区域+是G1的名字由来(garbage first)
G1 GC被称为并发回收器(concurrent collector)
因为标记老年代中不使用的对象和应用程序线程同时发生
G1并不是完全并发的,因为新生代的标记和压缩仍需要暂停所有应用程序线程
老年代的压缩也是在应用程序线程暂停期间完成的

G1的四个逻辑操作

1.新生代回收
2.后台并发标记周期
3.混合回收
4.必要的Full GC

请添加图片描述

并发模式失败 concurrent mode failure

G1 GC启动了一个标记周期,但是老年代在这个标记周期完成之前被填满了。
51.408: [GC concurrent-mark-start]
65.473: [Full GC 4095M->1395M(4096M), 6.1963770 secs]
[Times: user=7.87 sys=0.00, real=6.20 secs]
71.669: [GC concurrent-mark-abort]
[51.408][info][gc,marking ] GC(30) Concurrent Mark From Roots

[65.473][info][gc ] GC(32) Pause Full (G1 Evacuation Pause)
4095M->1305M(4096M) 60,196.377

[71.669s][info][gc,marking ] GC(30) Concurrent Mark From Roots 191ms
[71.669s][info][gc,marking ] GC(30) Concurrent Mark Abort

这种失败应该增加堆的大小,G1的后台处理必须更快,或者优化标记周期

晋升失败 promotion failure

G1完成了标记周期,已经开始执行Mixed GC以清理老年代区域
在还没有清理出足够的空间之前,有太多的对象从新生代晋升。导致老年代的空间还是用完了。
2226.224: [GC pause (mixed)
2226.440: [SoftReference, 0 refs, 0.0000060 secs]
2226.441: [WeakReference, 0 refs, 0.0000020 secs]
2226.441: [FinalReference, 0 refs, 0.0000010 secs]
2226.441: [PhantomReference, 0 refs, 0.0000010 secs]
2226.441: [JNI Weak Reference, 0.0000030 secs]
(to-space exhausted), 0.2390040 secs]

[Eden: 0.0B(400.0M)->0.0B(400.0M)
Survivors: 0.0B->0.0B Heap: 2006.4M(2048.0M)->2006.4M(2048.0M)]
[Times: user=1.70 sys=0.04, real=0.26 secs]
2226.510: [Full GC (Allocation Failure)
2227.519: [SoftReference, 4329 refs, 0.0005520 secs]
2227.520: [WeakReference, 12646 refs, 0.0010510 secs]
2227.521: [FinalReference, 7538 refs, 0.0005660 secs]
2227.521: [PhantomReference, 168 refs, 0.0000120 secs]
2227.521: [JNI Weak Reference, 0.0000020 secs]
2006M->907M(2048M), 4.1615450 secs]
[Times: user=6.76 sys=0.01, real=4.16 secs]

[2226.224 s][info][gc ] GC(26) Pause Young (Mixed)
(G1 Evacuation Pause)
2048m->2006 M(2048 M) 26.129 ms

[2226.510 s][info][gc,start ] GC(27) Pause Full (G1 Evacuation Pause)

混合回收需要执行的更快。

疏散失败 evacuation failure

当执行新生代回收,如果S空间和O空间没有足够空间容纳幸存对象
会出现一种特别的young gc
60.238: [GC pause (young) (to-space overflow), 0.41546900 secs]
[60.238s][info][gc,start ] GC(28) Pause Young (Concurrent Start)
(G1 Evacuation Pause)
[60.238s][info][gc,task ] GC(28) Using 4 workers of 4
for evacuation
[60.238s][info][gc ] GC(28) To-space exhausted

表明堆已经非常满或者碎片化严重,G1会进行补偿,但是结果可能更糟:JVM进而执行Full GC,这个时候暂停时间会更长

巨型对象分配失败(humongous allocation failure)

分配巨型对象的应用可能会触发另一种Full GC JDK 11日志如下
[3023.091s][info][gc,start ] GC(54) Pause Full (G1 Humongous Allocation)

元数据GC阈值 metadata GC threshold

元空间本质上是一个独立的堆,并且独立于主堆进行回收,并不是通过G1进行回收的
当需要元空间回收,G1会在主堆上执行Full GC

0.0535: [GC (Metadata GC Threshold) [PSYoungGen: 34113K->20388K(291328K)]
73838K->60121K(794112K), 0.0282912 secs]
[Times: user=0.05 sys=0.01, real=0.03 secs]
0.0566: [Full GC (Metadata GC Threshold) [PSYoungGen: 20388K->0K(291328K)]
[ParOldGen: 39732K->46178K(584192K)] 60121K->46178K(875520K),
[Metaspace: 59040K->59036K(1101824K)], 0.1121237 secs]
[Times: user=0.28 sys=0.01, real=0.11 secs]

元空间可以被回收,可以调整大小,而不必进行Full GC ON JDK 11 AND AFTER VERSION

优化G1

优化G1 GC的主要目标是确保没有因并发模式失败或疏散失败而产生FullGC
该技术也适用于优化频繁发生的Young GC必须等待根区域扫描完成的情况
在JDK8中优化FullGC的原因是单线程执行,比平时造成的停顿时间更长
JDK11 FullGC使用多线程执行,造成的停顿时间更短但是需要更多的时钟周期

优化可以尽量减少运行过程中的停顿次数
增加老年代大小
增加后台线程数量 linux commandline cat /proc/sys/kernel/threads-max
更频繁的执行G1 GC后台活动
增加Mixed GC周期工作量

主要通过一个参数进行优化
-XX:MaxGCPauseMillis=N 默认200毫秒
如果该标志的值减小,新生代大小将收缩以满足暂停时间目标,YGC会执行的更加频繁
如果满足停顿目标,减少MixedGC期间可以回收老年代,会提高并发收集失败的概率

优化G1后台线程

G1并发标记周期和应用程序的竞争出现是因为清理老年代的速度必须比晋升新对象的速度快
增加后台并发进程处理这个问题
G1 使用两组线程
1.通过-XX:ParallelGCThreads=N 设置
这个值会影响应用程序线程暂停阶段的线程数量
暂停阶段是新生代回收,混合回收,并发标记周期中应用程序必须暂停的阶段

2.-XX:ConcGCThread=N
影响并发标记的线程数量
ConcGCThreads = (ParallelGCThreads + 2) / 4

增加后台线程会缩短并发周期,让G1在Mixed GC过程中其他线程再次填满老年代的时候更容易的完成老年代的回收
CPU需要考虑到其中

优化G1 GC的运行频率

GC提前开始后台标记周期,也可以尽量减少FullGC
当堆达到-XX:InitiatingHeapOccupancyPercent=N设定的占用率,这个提前标记的周期才会开始
默认值是45,表示老年代占整个堆的比例
太大太小多不好,打了执行fullgc,小了执行后台gc更多

优化G1的Mixed GC周期

一个并发周期结束后,知道之前标记的所有老年代全部回收才会开始新的并发标记周期
让G1提前开始并发标记一个方法是在Mixed周期中处理更多的区域
Mixed工作量取决于三个因素
1.有多少区域被发现其中大部分是垃圾对象,目前没有办法可以直接影响这一点
2.G1处理区域是MixedGC周期的最大总次数
通过-XX:G1MixedGCCountTarget=N 默认8
减少可以解决晋升失败问题,代价是GC停顿时间更长–当并发完成开始mGC清理老年代的时候发现大量新对象填满老年代
过长的话会导致并发模式失败–并发周期未结束导致老年代再次被填满
3.GC可接受的最大停顿毫秒数(MaxGCPauseMillis)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

P("Struggler") ?

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

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

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

打赏作者

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

抵扣说明:

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

余额充值