当前位置:首页 > 科技  > 软件

Java11 的 G1 垃圾收集器

来源: 责编: 时间:2023-11-16 09:39:41 195观看
导读大家好,我是【运维开发故事公众号】的 Java 程序员老郑。JVM 是我们从事 Java 项目和开发都需要具备的非常底层的基础知识。首先我先抛出以下几个问题:很多服务需要过一段时间重启一次,如果不重启系统就会越来越慢?突然一

D9628资讯网——每日最新资讯28at.com

大家好,我是【运维开发故事公众号】的 Java 程序员老郑。JVM 是我们从事 Java 项目和开发都需要具备的非常底层的基础知识。D9628资讯网——每日最新资讯28at.com

首先我先抛出以下几个问题:D9628资讯网——每日最新资讯28at.com

  • 很多服务需要过一段时间重启一次,如果不重启系统就会越来越慢?
  • 突然一个中间件挂了一段时间过后,但是一些不相关的服务越来越卡,后面 OOM?
  • 上线一个功能过后,CPU 就飙升到 100%,但是服务还是正常运行?
  • 服务的某一个 CPU 出现有规律的,周期性的尖刺该如何解决?

作为 5 年以上工作经验的技术人员,或多或少在系统维护,系统保障,系统调优遇到过上面的这几个场景,你可能是通过重启,调整一些 jvm 参数解决,如果大家需要深入的探究找到问题的原因,可以耐心看看下文我对 G1 的一些总结。D9628资讯网——每日最新资讯28at.com

本文讲哪些东西?

  • 堆布局(以 Region 为基础划分:新生代(Eden 区、Survivor 区)、年老代、Humongous 区域)
  • 垃圾收集周期
  • GC 运作过程:初始标记、并发标记、最终标记、筛选回收
  • GC 类型:Minor GC、Full GC 、Mixed GC
  • CSet (年轻代需要收集的 Region 集合就是 CSet)
  • 跨代引用
  • 停顿预测模型
  • GC 日志分析

G1 内存堆布局

G1 的英文全称是 Garbagge First,是一个有分代,按照 Region 的方式进行内存布局的垃圾收集器。D9628资讯网——每日最新资讯28at.com

D9628资讯网——每日最新资讯28at.com

上图,我将一些 Region 标明了 H,它代表Humongous,这表示这些 Region 存储的是巨大对象(humongous object,H-obj),即大小大于等于 region 一半的对象。H-obj 有如下几个特征:D9628资讯网——每日最新资讯28at.com

  • H-obj 直接分配到了old gen,防止了反复拷贝移动。
  • H-obj 在 global concurrent marking 阶段的 cleanup 和 full GC阶段回收。
  • 在分配 H-obj 之前先检查是否超过 initiating heap occupancy percent 和 the marking threshold, 如果超过的话,就启动 global concurrent marking,为的是提早回收,防止 evacuation failures 和 full GC。

GC 类型

  1. Young GC,垃圾收集范围:年轻代区域 + 大对象区。
  2. Mixed GC,垃圾收集范围:年轻代区域 + 老年区 + 大对象区。
  3. Full GC,垃圾收集范围:年轻代区域 + 老年区 + 大对象区 + 元空间。

Collection Set (收集区域)

Collection Set 就是我们垃圾收集器的一个区域,在不同的垃圾回收阶段,会有不同的区域。D9628资讯网——每日最新资讯28at.com

  • Young GC, 垃圾收集区域包括:年轻代区域 + 大对象区。
  • Mixed GC, 垃圾收集区域包括:年轻代区域 + 老年区 + 大对象区。

跨代引用

Young GC 主要是清理,新生代中的对象,我们知道整个堆空间包括老年代,新生代,我们在 Young GC 过程中会去找 GCRoots 然后判断对象是是否可达, 如果不可达,如果可达就标记。如果对于老年代中引用新生代的对象,我们如果要找出来就就需要对老年代进行全扫描,这样是不太现实的。所以 G1 通过记忆集的形式记录了老年代对新生代的引用。具体在 G1 中通过 CarTable 来实现记忆集。D9628资讯网——每日最新资讯28at.com

D9628资讯网——每日最新资讯28at.com

RSet(记忆集)

记录了其它 Region 中的对象到 Region 的引用。RSet 的价值在于使得垃圾回收不需要扫描整个堆,能够快速定位到真正引用它的堆对象地址。ReSet 本身就是一个 Hash 表,存储在新生代的每个 Region 中。但是存储需要消耗空间,多的能达到百分之 20。因此G1对内存的空间要求较高(小空间没资本玩),空间越大性能越彪悍。D9628资讯网——每日最新资讯28at.com

CardTable (卡表)

由于新生代GC时,需要扫描整个old区,效率非常低。所以old区就是用卡表的方式进行一次逻辑分区。一般一页卡表的大小是2的n次幂。每一个区域也是用Key,Value结构进行记录。每一区域记录为Key不重复,Value则记录这片区域的老年代对象与新生代对象是否存在引用关系,存在则标记为1,否则为0。记录完毕后把value为1的key作为ReSet的key进行记录,并且ReSet的value存储引用,从而提高跨代引用的查询效率。D9628资讯网——每日最新资讯28at.com

停顿预测模型

所有的预测都是基于历史的拟合,HotSpot使用了基于方差与标准差的技术。参考:https://sdww2348115.github.io/jvm/g1/PausePredictionModel。D9628资讯网——每日最新资讯28at.com

G1 垃圾收集周期

D9628资讯网——每日最新资讯28at.com

图片来源 Oracle 官网D9628资讯网——每日最新资讯28at.com

G1 有两个阶段,它会在这两个阶段往返,分别是 Young-only,Space Reclamation.D9628资讯网——每日最新资讯28at.com

  • Young-only 包含一系列的操作,如果长期存活的对象会逐渐转移到 Old gen。
  • Space Reclamation G1 会递进地回收 Old gen 的空间,同时也处理 Young region。

图是来自 Oracle 上对 GC 周期的描述,实心圆都表示一次 GC 停顿D9628资讯网——每日最新资讯28at.com

  • 蓝色 Young-only。
  • 黄色 标记过程的停顿。
  • 红色 Mixed GC 停顿。

在几次 GC 后,Old gen 的对象占有比超过了 InitiatingHeapOccupancyPercent (简称为IHOP,默认值为45,这个值是启动并发标记的阈值,当老年代使用内存占用堆内存的45%启动并发标记。如果该区域过大,可能会导致mixed gc跟不上内存分配的速度从而导致full gc ),gc 就会进入并发标记准备 (Concurrent Mark)。D9628资讯网——每日最新资讯28at.com

  • G1 在每一次 Young 回收中都会查找活对象 (有引用的对象)。
  • G1 在 old region 并发查找存活对象。
  • 是 Concurrent Marking。
  • 可能花费很长时间。
  • 不会停止 Java 应用。
  • G1 没有活对象的引用信息是不能进行垃圾回收的。
  • Mixed GC 依赖 Concurrent Mark。D9628资讯网——每日最新资讯28at.com

回到 Full GC,从上面简单分析得出,Full GC 发生是没有足够的 free region,如果堆是足够大的,Mixed gc 没有回收足够的 old region,或者 concurrent mark 没法及时完成,都可能会导致 full gc。D9628资讯网——每日最新资讯28at.com

GC 日志分析

下面是网上找的一个 GC 日志案例,解析如下(配合 G1 垃圾收集周期结合来看):D9628资讯网——每日最新资讯28at.com

[gc,start      ] GC(44265) Pause Young (Normal) (G1 Evacuation Pause)[gc,task       ] GC(44265) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44265)   Pre Evacuate Collection Set: 0.1ms[gc,phases     ] GC(44265)   Evacuate Collection Set: 101.8ms[gc,phases     ] GC(44265)   Post Evacuate Collection Set: 3.2ms[gc,phases     ] GC(44265)   Other: 2.7ms[gc,heap       ] GC(44265) Eden regions: 1850->0(1851)[gc,heap       ] GC(44265) Survivor regions: 70->69(240)[gc,heap       ] GC(44265) Old regions: 766->768[gc,heap       ] GC(44265) Humongous regions: 20->19[gc,metaspace  ] GC(44265) Metaspace: 193280K->193280K(1230848K)[gc            ] GC(44265) Pause Young (Normal) (G1 Evacuation Pause) 21642M->6843M(25600M) 107.561ms[gc,cpu        ] GC(44265) User=1.31s Sys=0.00s Real=0.11s[gc,start      ] GC(44266) Pause Young (Normal) (G1 Evacuation Pause)[gc,task       ] GC(44266) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44266)   Pre Evacuate Collection Set: 0.1ms[gc,phases     ] GC(44266)   Evacuate Collection Set: 99.8ms[gc,phases     ] GC(44266)   Post Evacuate Collection Set: 3.3ms[gc,phases     ] GC(44266)   Other: 2.7ms[gc,heap       ] GC(44266) Eden regions: 1851->0(1854)[gc,heap       ] GC(44266) Survivor regions: 69->66(240)[gc,heap       ] GC(44266) Old regions: 768->772[gc,heap       ] GC(44266) Humongous regions: 20->19[gc,metaspace  ] GC(44266) Metaspace: 193280K->193280K(1230848K)[gc            ] GC(44266) Pause Young (Normal) (G1 Evacuation Pause) 21659M->6848M(25600M) 105.713ms[gc,cpu        ] GC(44266) User=1.29s Sys=0.01s Real=0.10s[gc,start      ] GC(44267) Pause Young (Normal) (G1 Evacuation Pause)[gc,task       ] GC(44267) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44267)   Pre Evacuate Collection Set: 0.1ms  //初始标记,查找 gc root [gc,phases     ] GC(44267)   Evacuate Collection Set: 89.8ms     //并发标记[gc,phases     ] GC(44267)   Post Evacuate Collection Set: 3.5ms //清理工作[gc,phases     ] GC(44267)   Other: 2.7ms[gc,heap       ] GC(44267) Eden regions: 1854->0(1856)[gc,heap       ] GC(44267) Survivor regions: 66->64(240)[gc,heap       ] GC(44267) Old regions: 772->775[gc,heap       ] GC(44267) Humongous regions: 20->19[gc,metaspace  ] GC(44267) Metaspace: 193280K->193280K(1230848K)[gc            ] GC(44267) Pause Young (Normal) (G1 Evacuation Pause) 21688M->6859M(25600M) 95.891ms[gc,cpu        ] GC(44267) User=1.16s Sys=0.00s Real=0.10s[gc,start      ] GC(44268) Pause Young (Normal) (G1 Evacuation Pause)                 // Young GC[gc,task       ] GC(44268) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44268)   Pre Evacuate Collection Set: 0.1ms[gc,phases     ] GC(44268)   Evacuate Collection Set: 100.5ms[gc,phases     ] GC(44268)   Post Evacuate Collection Set: 3.8ms[gc,phases     ] GC(44268)   Other: 2.8ms[gc,heap       ] GC(44268) Eden regions: 1856->0(1855)[gc,heap       ] GC(44268) Survivor regions: 64->65(240)[gc,heap       ] GC(44268) Old regions: 775->777[gc,heap       ] GC(44268) Humongous regions: 20->19[gc,metaspace  ] GC(44268) Metaspace: 193280K->193280K(1230848K)[gc            ] GC(44268) Pause Young (Normal) (G1 Evacuation Pause) 21715M->6876M(25600M) 107.037ms[gc,cpu        ] GC(44268) User=1.30s Sys=0.00s Real=0.11s[gc,start      ] GC(44269) Pause Young (Concurrent Start) (G1 Humongous Allocation)  // 并发阶段[gc,task       ] GC(44269) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44269)   Pre Evacuate Collection Set: 0.6ms[gc,phases     ] GC(44269)   Evacuate Collection Set: 90.9ms[gc,phases     ] GC(44269)   Post Evacuate Collection Set: 3.2ms[gc,phases     ] GC(44269)   Other: 2.9ms[gc,heap       ] GC(44269) Eden regions: 1519->0(1855)[gc,heap       ] GC(44269) Survivor regions: 65->65(240)[gc,heap       ] GC(44269) Old regions: 777->777[gc,heap       ] GC(44269) Humongous regions: 19->19[gc,metaspace  ] GC(44269) Metaspace: 193280K->193280K(1230848K)[gc            ] GC(44269) Pause Young (Concurrent Start) (G1 Humongous Allocation) 19024M->6883M(25600M) 97.391ms[gc,cpu        ] GC(44269) User=1.16s Sys=0.01s Real=0.10s[gc            ] GC(44270) Concurrent Cycle                                          // 完成 clearup[gc,marking    ] GC(44270) Concurrent Clear Claimed Marks[gc,marking    ] GC(44270) Concurrent Clear Claimed Marks 0.562ms[gc,marking    ] GC(44270) Concurrent Scan Root Regions[gc,marking    ] GC(44270) Concurrent Scan Root Regions 719.931ms[gc,marking    ] GC(44270) Concurrent Mark (280799.914s)[gc,marking    ] GC(44270) Concurrent Mark From Roots[gc,task       ] GC(44270) Using 3 workers of 3 for marking[gc,marking    ] GC(44270) Concurrent Mark From Roots 2268.905ms[gc,marking    ] GC(44270) Concurrent Preclean[gc,marking    ] GC(44270) Concurrent Preclean 3.078ms[gc,marking    ] GC(44270) Concurrent Mark (280799.914s, 280802.186s) 2272.068ms[gc,start      ] GC(44270) Pause Remark[gc,stringtable] GC(44270) Cleaned string and symbol table, strings: 87967 processed, 92 removed, symbols: 442773 processed, 13 removed[gc            ] GC(44270) Pause Remark 13740M->13740M(25600M) 32.599ms[gc,cpu        ] GC(44270) User=0.29s Sys=0.00s Real=0.04s[gc,marking    ] GC(44270) Concurrent Rebuild Remembered Sets            //重构记忆集[gc,marking    ] GC(44270) Concurrent Rebuild Remembered Sets 1906.792ms[gc,start      ] GC(44270) Pause Cleanup[gc            ] GC(44270) Pause Cleanup 18019M->18019M(25600M) 0.782ms[gc,cpu        ] GC(44270) User=0.00s Sys=0.01s Real=0.00s[gc,marking    ] GC(44270) Concurrent Cleanup for Next Mark[gc,marking    ] GC(44270) Concurrent Cleanup for Next Mark 25.530ms[gc            ] GC(44270) Concurrent Cycle 4963.833ms[gc,start      ] GC(44271) Pause Young (Prepare Mixed) (G1 Evacuation Pause)  // Space Reclamation 阶段了,多个 Mixed GC 会进行[gc,task       ] GC(44271) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44271)   Pre Evacuate Collection Set: 0.1ms[gc,phases     ] GC(44271)   Evacuate Collection Set: 102.6ms[gc,phases     ] GC(44271)   Post Evacuate Collection Set: 3.7ms[gc,phases     ] GC(44271)   Other: 3.9ms[gc,heap       ] GC(44271) Eden regions: 1855->0(98)[gc,heap       ] GC(44271) Survivor regions: 65->62(240)[gc,heap       ] GC(44271) Old regions: 777->778[gc,heap       ] GC(44271) Humongous regions: 21->19[gc,metaspace  ] GC(44271) Metaspace: 193271K->193271K(1230848K)[gc            ] GC(44271) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 21739M->6869M(25600M) 110.034ms[gc,cpu        ] GC(44271) User=1.32s Sys=0.01s Real=0.10s[gc,start      ] GC(44272) Pause Young (Mixed) (G1 Evacuation Pause)[gc,task       ] GC(44272) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44272)   Pre Evacuate Collection Set: 0.4ms[gc,phases     ] GC(44272)   Evacuate Collection Set: 150.8ms[gc,phases     ] GC(44272)   Post Evacuate Collection Set: 3.2ms[gc,phases     ] GC(44272)   Other: 2.3ms[gc,heap       ] GC(44272) Eden regions: 98->0(149)[gc,heap       ] GC(44272) Survivor regions: 62->11(20)[gc,heap       ] GC(44272) Old regions: 778->547[gc,heap       ] GC(44272) Humongous regions: 19->19[gc,metaspace  ] GC(44272) Metaspace: 193271K->193271K(1230848K)[gc            ] GC(44272) Pause Young (Mixed) (G1 Evacuation Pause) 7653M->4605M(25600M) 156.486ms[gc,cpu        ] GC(44272) User=1.95s Sys=0.01s Real=0.15s[gc,start      ] GC(44273) Pause Young (Mixed) (G1 Evacuation Pause)[gc,task       ] GC(44273) Using 13 workers of 13 for evacuation[gc,phases     ] GC(44273)   Pre Evacuate Collection Set: 0.2ms[gc,phases     ] GC(44273)   Evacuate Collection Set: 122.9ms[gc,phases     ] GC(44273)   Post Evacuate Collection Set: 2.0ms[gc,phases     ] GC(44273)   Other: 3.1ms[gc,heap       ] GC(44273) Eden regions: 149->0(1900)[gc,heap       ] GC(44273) Survivor regions: 11->20(20)[gc,heap       ] GC(44273) Old regions: 547->520[gc,heap       ] GC(44273) Humongous regions: 19->19[gc,metaspace  ] GC(44273) Metaspace: 193271K->193271K(1230848K)[gc            ] GC(44273) Pause Young (Mixed) (G1 Evacuation Pause) 5797M->4468M(25600M) 128.036ms[gc,cpu        ] GC(44273) User=1.57s Sys=0.01s Real=0.12s

上面是连续几次 GC 的日志,可以对照着 GC 周期来看。D9628资讯网——每日最新资讯28at.com

  • GC (44265) 是一次普通的 Young GC里面信息有各种 Region 的变化。

这里简单说一下 humongous 对象的处理,humongous 对象在 G1 中是被特殊对待的,G1 只决定它们是否生存,回收他们占用的空间,从不会移动它们。D9628资讯网——每日最新资讯28at.com

  • Young-Only 阶段,humongous regions 可能会被回收。
  • Space-Reclamation,humongous regions 可能会被回收。
  • GC (44269) 开始进入并发阶段。
  • GC (44270) 完成了 Cleanup,紧接着一个 Prepare Mixed GC (44271) 的垃圾收集,对应周期虚线右边的蓝实心圆。
  • GC (44272) 之后就是 Space Reclamation 阶段了,多个 Mixed GC 会进行。

JVM 性能监控工具

我们可以通过以下几种工具辅助分析 JVM 性能瓶颈:D9628资讯网——每日最新资讯28at.com

综合组件:D9628资讯网——每日最新资讯28at.com

  • VisualVM
  • Glowroot
  • https://arthas.aliyun.com/。

thread dump 分析:D9628资讯网——每日最新资讯28at.com

  • https://fastthread.io/。

gc 日志分析:D9628资讯网——每日最新资讯28at.com

  • https://gceasy.io/gc-index.jsp。

heap dump 分析:D9628资讯网——每日最新资讯28at.com

  • https://www.ibm.com/support/pages/ibm-heapanalyzer。
  • https://projects.eclipse.org/projects/tools.mat。

参考资料

【GC 停顿预测模型】D9628资讯网——每日最新资讯28at.com

  • http://www.narihiro.info/g1gc-impl-book/scheduling.html。
  • https://sdww2348115.github.io/jvm/g1/PausePredictionModel。

【垃圾收集器执行过程】D9628资讯网——每日最新资讯28at.com

  • https://bugs.openjdk.org/browse/JDK-8295118。
  • https://my.oschina/u/4273516/blog/4550072。

【跨代引用】D9628资讯网——每日最新资讯28at.com

  • https://blog.csdn/weixin_47184173/article/details/113627337。

【空闲时自动将Java堆内存返回给操作系统】。D9628资讯网——每日最新资讯28at.com

  • https://openjdk.org/jeps/346

【其他】D9628资讯网——每日最新资讯28at.com

  • https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/comline.htm#JFRUH197。
  • https://www.redhat.com/en/blog/part-1-introduction-g1-garbage-collector。
  • https://blog.csdn/qq_16500963/article/details/132133125。
  • http://cs.williams.edu/~dbarowy/cs334s18/assets/p37-detlefs.pdf。
  • https://tech.meituan.com/2016/09/23/g1.html。
  • https://hllvm-group.iteye.com/group/topic/44381。

本文链接:http://www.28at.com/showinfo-26-26558-0.htmlJava11 的 G1 垃圾收集器

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 高效设计企业营销系统的三种方案复盘

下一篇: 怎么理解 React Server Component 和 Next.js 的关系

标签:
  • 热门焦点
  • 一篇文章带你了解 CSS 属性选择器

    一篇文章带你了解 CSS 属性选择器

    属性选择器对带有指定属性的 HTML 元素设置样式。可以为拥有指定属性的 HTML 元素设置样式,而不仅限于 class 和 id 属性。一、了解属性选择器CSS属性选择器提供了一种简单而
  • 2023年,我眼中的字节跳动

    2023年,我眼中的字节跳动

    此时此刻(2023年7月),字节跳动从未上市,也从未公布过任何官方的上市计划;但是这并不妨碍它成为中国最受关注的互联网公司之一。从2016-17年的抖音强势崛起,到2018年的“头腾
  • 慕岩炮轰抖音,百合网今何在?

    慕岩炮轰抖音,百合网今何在?

    来源:价值研究所 作者:Hernanderz“难道就因为自己的一个产品牛逼了,从客服到总裁,都不愿意正视自己产品和运营上的问题,选择逃避了吗?”这一番话,出自百合网联合创
  • 破圈是B站头上的紧箍咒

    破圈是B站头上的紧箍咒

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之每年的暑期档都少不了瞄准追剧女孩们的古偶剧集,2021年有优酷的《山河令》,2022年有爱奇艺的《苍兰诀》,今年却轮到小破站抓住了追
  • 腾讯VS网易,最卷游戏暑期档,谁能笑到最后?

    腾讯VS网易,最卷游戏暑期档,谁能笑到最后?

    作者:无锈钵来源:财经无忌7月16日晚,上海1862时尚艺术中心。伴随着幻象的精准命中,硕大的荧幕之上,比分被定格在了14:12,被寄予厚望的EDG战队以绝对的优势战胜了BLG战队,拿下了总决
  • 东方甄选单飞:有些鸟注定是关不住的

    东方甄选单飞:有些鸟注定是关不住的

    文/彭宽鸿编辑/罗卿东方甄选创始人俞敏洪带队的“7天甘肃行”直播活动已在近日顺利收官。成立后一年多时间里,东方甄选要脱离抖音自立门户的传闻不绝于耳,“7
  • 余承东:AI大模型技术的发展将会带来下一代智能终端操作系统的智慧体验

    余承东:AI大模型技术的发展将会带来下一代智能终端操作系统的智慧体验

    8月4日消息,2023年华为开发者大会(HDC.Together)今天正式开幕,华为发布HarmonyOS 4、全新升级的鸿蒙开发套件、HarmonyOS Next开发者预览版本等一系列
  • 三星Galaxy Z Fold/Flip 5国行售价曝光 :最低7499元/12999元起

    三星Galaxy Z Fold/Flip 5国行售价曝光 :最低7499元/12999元起

    据官方此前宣布,三星将于7月26日也就是明天在韩国首尔举办Unpacked活动,届时将带来带来包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy
  • iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
Top