JVM垃圾收集器——G1

导航

  • 引言
  • 一、G1 介绍
    • 1.1 适用场景
    • 1.2 设计初衷
    • 1.3 关注焦点
    • 1.4 工作模式
    • 1.5 堆的逻辑结构
    • 1.6 主要收集目标
    • 1.7 停顿预测模型
    • 1.8 拷贝和压缩
    • 1.9 与 CMS 和 Parallel 收集器的比较
    • 1.10 固定停顿目标
  • 二、堆的逻辑分区
    • 2.1 region
    • 2.2 CSet
    • 2.3 RSet
    • 2.4 Card Table
  • 三、G1 的工作原理
    • 3.1 YGC
    • 3.2 Mixed GC
    • 3.3 工作流程
  • 四、常用的G1调优参数和建议
    • 4.1 G1常见命令行参数及其默认值
    • 4.2 调优建议
    • 4.3 to-space 的溢出和耗尽
    • 4.4 Humongous 对象及其分配

引言

本文针对 Hotspot 虚拟机的 G1 垃圾收集器进行总结和归纳,适用于JDK 8。

文章内容以 Garbage-First Garbage Collector 和 Garbage-First Garbage Collector Tuning 两篇官方文章为主,结合 JVM面试必问:G1垃圾回收器 技术社区分享汇总。

一、G1 介绍

G1 是 Hotspot 虚拟机在 jdk 8 之后正式(java7处于试验阶段)推出的一款针对多核CPU、大内存的服务器端应用程序提供服务的垃圾收集器。

1.1 适用场景

通用需要:大堆空间(>6G)、低延迟(< 0.5s)
业务需要:堆中有 超过50% 的存活对象,对象的分配率和提升率差异很大。

1.2 设计初衷

实现高吞吐量的同时获得尽可能短暂的STW停顿。

1.3 关注焦点

为用户提供一种更大的堆且低延迟的解决方案。例如,6G的堆,且延迟基本可以稳定在小于0.5秒。

1.4 工作模式

面向整个堆空间进行GC,某些阶段如并发标记,可与工作线程并发执行。

1.5 堆的逻辑结构

整个堆被分成一个个大小相等且物理地址连续的 region(分区)。region大小在1M~32M不等(2的幂),取决于堆的大小,但总数不会超过2048。

为兼容传统的分代机制,eden、survivor、old 这些年代概念依然存在,但在G1中是以 region 为单位,分散在堆中(相同或不同的年代之间不一定连续)。

1.6 主要收集目标

Garbage First 垃圾优先。

通过全局的并发标记,G1可以得知哪些区域大部分都是垃圾,G1会首先收集和压缩这些region。优先收集垃圾更多的 region,就意味着可以以更短的时间获得更大的收益。

1.7 停顿预测模型

G1会使用一种称为“暂停预测”的模型,来评估需要收集多少region,从而限制停顿时间(STW)。

1.8 拷贝和压缩

对于内存碎片问题,G1在GC的过程中会将一个或多个 region中的存活对象拷贝、压缩到一个新的region 中,以减少堆空间的碎片化。

这项操作必须是 STW的,因为要拷贝到新的region,如果应用程序不停的分配对象,很明显会严重干扰拷贝压缩的过程。

这个过程会在多处理器上并行执行以降低停顿时长。因此,每次GC,G1都在努力减少内存碎片。

1.9 与 CMS 和 Parallel 收集器的比较

G1要优于这两种收集器。

CMS 默认是不进行内存压缩的,所以会产生严重的内存碎片问题;
Parallel收集器会对整个堆进行数据压缩,这会导致严重的STW。

1.10 固定停顿目标

用户可以设定STW的停顿时间,但G1只是 大概率能够满足而并非绝对 。它会根据之前GC的情况,会构建一个相当精确的“收集成本模型”,以此来决定要收集哪些region以及收集多少region。

a reasonably accurate model of the cost of collecting the regions

二、堆的逻辑分区

2.1 region

的
上图是Oracle官网给出的G1收集器对整个堆结构的逻辑划分示例。

G1 将整个堆划分为一个个相同大小的 region。它覆盖了一块连续的内存空间,大小在 1M ~ 32M不定,但一定是 2 的幂,默认数量是2048个。

和传统的垃圾收集器,如Serial、Parallel、CMS等等不同,G1只是在逻辑上分代
也就是说,G1摒弃了传统的大块分代空间的做法,以 region 为单元,将 region标记为年轻代或老年代,这些region共同组成年轻代或老年代的整体大小。而且G1可以随着运行情况和策略的变化动态调整年轻代或老年代region的数量以此来调整对应分代的大小。
在这里插入图片描述

2.2 CSet

CSet ,Collection Set ,它是一组可被回收的 region 集合。在后面讲到的 YGC 中,会提到它的使用。CSet 中的 region 既可以是年轻代,也可以是老年代,G1 会将 CSet中存活的对象拷贝、压缩到新的region,CSet 大概占用堆空间的 1% 大小。

2.3 RSet

对于多数分代收集器,YGC 会先收集堆中年轻代的内存空间,这是一种增量收集的方式。G1作为逻辑分代的收集器,同样属于增量式垃圾收集器。

在进行增量收集的时候,收集器需要知道未收集的对象有没有指向正在收集的对象的引用。对于 YGC 来说,通常是老年代指向年轻代。而 RSet 就是这样一种记忆结构,专门用于存储一组其他对象指向当年对象的引用

对于 G1 而言,RSet 是位于 region 中。之所以设计这样一个结构,就是为了在做 GC 标记的时候,避免全图扫描。这也是 G1 高效 GC 的关键手段之一。

2.4 Card Table

Card Table 是一中特殊类型的 RSet。

A card table is a particular type of remembered set. —— Card Tables and Concurrent Phases

Hotspot 虚拟机使用一组字节数组来实现 Card Table。每个字节代表一个 card,card又对应堆中的一块连续内存地址。如果引用关系发生改变,就将对应的 card 标记为 dirty,在 remark 阶段就只需要扫描这些 dirty card 就可以快速追踪引用发生变化的对象。

三、G1 的工作原理

G1的工作过程是一个非常复杂的流程,包含很多可考虑的因素和条件。

3.1 YGC

YGC 又叫做 young collection 或 Minor GC,会有STW停顿。它是G1收集器的先锋兵,实际上不光是G1,其他收集器在最初发生GC的时候都要先进行 YGC。

Java中的大多数对象都主要分配在堆的 Eden 区,它隶属于年轻代,同时又随着应用程序的运行快速“消亡”(对象不可达),因此 YGC 是回收这些对象内存空间的有效手段。

在 YGC 期间,G1会从 CSet 中获取需要收集的 eden 和 survivor 区。CSet 是 Collection Set 的缩写,它是用于记录需要做垃圾收集的 region集合。G1 通过将活动对象从 eden 和 survivor 区增量并行复制到一个或多个不同的新 region 来实现内存压缩,减少碎片。

不同对象的目标region取决于对象的分代年龄,当达到年龄阈值,就会分配到老年代 region 中,而年龄不足的,会被分配到 survivor region中,并被包含在下一次的YGC 或 Mixed GC的CSet中。

值得一提的是,在STW的YGC期间,还会额外做一些有备后用的操作,如初始标记,这个过程是后续执行并发标记的“必要前戏”,目标是标记出 GC roots 根节点,由于本身就需要STW,因此放在YGC的STW中完成是希望能够充分利用停顿时间,以此达到G1的设计目标——pause time goal。

3.2 Mixed GC

Mixed GC 是在 YGC 的基础之上,选择性的增加 old region 的清理。

在 YGC 的过程中,G1会进行初始标记工作,之后,G1的垃圾回收线程就会进入重要的并发标记环节。

concurrent mark 阶段是与用户线程并发执行的垃圾收集工作,可以被 YGC 的 STW 打断。其目标是标记出所有可达的对象三色标记算法+RSet)。

Concurrent marking phase: The G1 GC finds reachable (live) objects across the entire heap. This phase happens concurrently with the application, and can be interrupted by STW young garbage collections.

G1的设计目标是尽可能在用户设定的停顿时间之内完成垃圾收集,为了达到这一点,并发执行一部分工作是必要的,但带来的问题就是,并发工作的GC线程势必会占用原本应该去执行用户线程的CPU资源,造成的损失就是吞吐量的下降官方给出的参考数据是 90%的用户线程时间和 10%的GC时间,而Parallel收集器的数据是 99% 的用户线程时间和 1%的GC时间)。

在并发标记阶段完成后,G1 的 YGC就会切换到 Mixed GC。

Mixed GC 阶段,G1会选择性的将一些 old region 加入到待收集的CSet 中,随 eden、survivor一同被G1清理。当G1清理了足够的 old region后(多次Mixed GC),G1就再次切换回 YGC,直到下次并发标记完成。

总之,G1的GC过程可以用这样一段描述来概括:

一开始G1使用YGC进行年轻代的垃圾清理,拷贝、压缩存活的对象,但当堆内存可用空间渐渐不足,例如活动对象占用超过整个堆的45%这一阈值时,就会触发G1的标记周期,这一过程以并发标记为主,当标记结束后,G1启动 MixedGC,它不仅会清理年轻代,还会选择性的清理一些老年代,当经过了几轮的 MixedGC之后,G1已经收集了足够多的老年代区域,此时堆的空间也不再紧张,G1就会再次切回YGC进行垃圾回收。

3.3 工作流程

YGC 和 Mixed GC 实际上是 G1 的两种工作模式,对于 Mixed GC,完整的工作流程应该包含以下几个阶段。

初始标记(Initial Mark): 这个阶段仅仅只是标记GC Roots能直接关联到的对象并修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确的可用的Region中创建新对象,这阶段需要停顿线程,但是耗时很短。而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿

并发标记(Concurrent Mark):从GC Roots开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出存活的对象,这阶段耗时较长,但是可以与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。

最终标记(Final Mark): 对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的 SATB 记录。

筛选回收(Live Data Counting and Evacuation): 负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划。可以自由选择多个Region来构成会收集,然后把回收的那一部分Region中的存活对象疏散到新的 region中。

四、常用的G1调优参数和建议

G1 是一个自适应的垃圾收集器,一些默认参数足可以高效工作。以下是 G1 相关的控制参数,了解这些参数的含义可以帮助我们更好的理解 G1 收集器。

4.1 G1常见命令行参数及其默认值

参考:Important Defaults

参数和默认值说明
-XX:G1HeapRegionSize=n设置 G1 的region的大小,1M ~ 32M ,2的幂。
目标是以-Xms为准大约有 2048 个 region
-XX:MaxGCPauseMillis=200设置期望的最大停顿时间。默认为 200ms
-XX:G1NewSizePercent=5年轻代占总堆的最小百分比。默认 5%。该参数为实验参数,必须在该参数前面设置-XX:+UnlockExperimentalVMOptions 解锁实验参数,才能生效
-XX:G1MaxNewSizePercent=60年轻代占总堆最大百分比,应和上一条参数互补。
-XX:ParallelGCThreads=n设置 STW 时垃圾收集线程数,将 n 设置为逻辑处理器的数量,但最大不要超过 8。如果逻辑处理器数量超过8,可以将 n 设置为逻辑处理器的 5/8 。
-XX:ConcGCThreads=n设置并行标记的线程数。可以将 n 设置为 ParallelGCThreads 参数的 1/4 。
-XX:InitiatingHeapOccupancyPercent=45设置足以触发初始标记的堆占用阈值。默认为总堆大小的 45%。
-XX:G1MixedGCLiveThresholdPercent=85设置 Mixed GC 开始回收老年代 region 的堆占用阈值,默认为 85%。这是一个实验性参数,须在该参数前面设置-XX:+UnlockExperimentalVMOptions 解锁实验参数,才能生效。
-XX:G1HeapWastePercent=5设置允许浪费的堆空间占比
-XX:G1OldCSetRegionThresholdPercent=10设置可以被 Mixed GC 回收的老年代 region 占比上限。默认为 10%
-XX:G1ReservePercent=10设置预留的空内存大小,以防 to survivor 区溢出。默认为 10%。如果你要调整该参数,请记得将总堆的大小也一同调整。

4.2 调优建议

  1. 年轻代的大小
    避免显式设置年轻代的大小,因为 G1 会根据停顿目标自动调整年轻代的分配大小。
  2. STW限定目标
    任何垃圾收集器都存在吞吐量和延迟的权衡。
    G1 GC 的吞吐量目标是 90% 的应用程序时间和 10% 的垃圾收集时间。而 Parallel 收集器是 99% 的应用程序时间和 1% 的垃圾收集时间。因此,如果想要优化吞吐量,就必须要降低延迟的标准。
  3. 调试 Mixed GC
    当你在调试 Mixed GC时,可以测试以下这些参数:
    -XX:InitiatingHeapOccupancyPercent:改变触发标记周期的阈值
    -XX:G1MixedGCLiveThresholdPercent 和 -XX:G1HeapWastePercent:改变 Mixed GC 的决策
    -XX:G1MixedGCCountTarget 和 -XX:G1OldCSetRegionThresholdPercent :调整 CSet 中老年代的数量

4.3 to-space 的溢出和耗尽

如果GC日志中出现"to-space overflow"或"to-space exhausted"这样的消息,就表示G1 GC没有足够的内存来存放 survivor 或提升的对象。

这种情况可能是由于堆已经达到了最大值。例如:

924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space exhausted), 0.1957310 secs]
924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space overflow), 0.1957310 secs]

可以尝试调整以下参数:

  • -XX:G1ReservePercent:调大该参数(以及相应的总堆大小)以增加 “to-space” 的预留空间。
  • -XX:InitiatingHeapOccupancyPercent:调小该参数,以更早的触发标记过程。
  • -XX:ConcGCThreads:调大该参数,以增加并行标记线程的数量。

4.4 Humongous 对象及其分配

humongous 意为“极大的,硕大的”。对于 G1 来说,只要对象大小超过了 region 的一半,都称为 humongous 对象。

humongous 对象会被直接分配到老年代的 humongous region,有时 humongous 对象可能会跨越多个 region 分区。

在G1分配 humongous 之前,都会检查标记阈值,如果有必要,就会触发初始标记,为 Mixed GC 做准备。

为了减少拷贝的开销,一般不会轻易拷贝压缩 humongous 对象,G1 会在恰当的时机压缩 humongous 对象。

如果发现因为 humongous 对象的分配而频繁触发Mixed GC,并且老年代还在不断飙升,那么可以适当增加 region 的大小,这样,以前的 humongous 对象就有可能不会超过 region 的一半,从而遵循常规分配策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

的mvc_简述PHP网站开发的MVC模式

为了提高开发时候的代码重用和开发速度&#xff0c;php使用了mvc的模式&#xff0c;主要是对代码的功能进行了分类&#xff0c;M&#xff1a;model主要是对数据库进行操作&#xff0c;v&#xff1a;view主要是前端html文件操作&#xff0c;c&#xff1a;controller主要是编写基…

CAP 原则与 BASE 理论

导航引言一、CAP 原则1.1 Consistency 一致性1.2 Available 可用性1.3 Partition tolerance 分区容错性1.4 CAP 的矛盾1.5 CAP 的组合场景二、BASE 理论2.1 基本可用2.2 软状态2.3 最终一致性2.3.1 因果一致性2.3.2 读自身所写2.3.3 会话一致性2.3.4 单调读一致性2.3.5 单调写一…

java 教室借用管理系统_[内附完整源码和文档] 基于JAVA语言的学生选课信息管理系统...

摘 要本系统运用Java面向对象的方法设计而成。近年来&#xff0c;学生选课系统越来越在高校学生群体中得到普及&#xff0c;其所承担的功能也变得越来越丰富&#xff0c;所起到的作用也变得越来越重要&#xff0c;在被学校学生重视的同时&#xff0c;也意味着它的功能要更加完善…

jMeter 模拟 web 高并发请求

导航一、jmeter 简介与下载二、接口压测设置三、实战演示一、jmeter 简介与下载 Apache JMeter是Apache组织开发的基于Java的压力测试工具。 最初被设计用于Web应用测试&#xff0c;但后来扩展到其他测试领域。JMeter 可以用于对服务器、网络或对象模拟巨大的负载&#xff0c…

实施文档_建设工程监理全套资料范本,Word文档附百份案例表格,超实用

建设工程监理全套资料范本&#xff0c;Word文档附百份案例表格&#xff0c;超实用在日常工作中&#xff0c;监理人员不仅需要经常跑腿儿检查&#xff0c;同时还需要提交许许多多的资料存档&#xff0c;甚至可能需要熬夜码字。今天整理的监理资料范本&#xff0c;既能让监理人员…

微服务架构 —— 服务雪崩与容错方案

导航一、什么是服务雪崩二、雪崩效应的三个核心原因三、容错四、业界常见容错思路五、常见容错组件一、什么是服务雪崩 服务雪崩 指的是微服务架构中&#xff0c;微服务各节点之间由于网络通信异常或微服务自身故障等问题&#xff0c;导致请求堆积、任务堆积&#xff0c;消耗和…

手游方舟怎么输入代码_明日方舟再次登顶失败,为了不发十连奖励,鹰角实力控分?...

在明日方舟新版本活动“孤岛风云”正式上线后&#xff0c;关于干员的强度和游戏剧情的讨论也在最近多了起来。尤其是在一周年卫星干员山落地&#xff0c;并且人气干员塞雷娅背后的故事揭晓之后&#xff0c;明日方舟的热度也在玩家圈子中迅速的攀升&#xff0c;成为近期话题量十…

Spring Cloud Alibaba —— Sentinel 入门

导航一、什么是Sentinel1.1 Sentinel 的优点二、整合 Sentinel 演示三、Sentinel控制台与微服务通信的原理四、Sentinel 流控演示一、什么是Sentinel Sentinel 是阿里开源的用于提供微服务架构容错方案的组件。它以流量作为切入点&#xff0c;从流量控制、熔断降级、系统负载保…

Spring Cloud Alibaba —— Sentinel 详细使用

导航引言一、Sentinel的两个基本概念二、流控规则2.1 基本选项2.2 高级选项三、熔断(降级)规则四、热点规则五、授权规则&#xff08;了解&#xff09;六、系统规则&#xff08;了解&#xff09;七、自定义异常返回八、SentinelResource九、Sentinel 规则持久化&#xff08;待补…

扫地机器人单扫和双扫_小米扫拖机器人体验:再见了,拖把君

小米在2016年首次推出了扫地机器人&#xff0c;凭借产品力和性价比&#xff0c;可以说为中国家庭的智能清洁概念普及&#xff0c;立下一功。不过&#xff0c;近两年因为一直没有推出扫拖一体产品&#xff0c;急得民间高手都开始自己动手给米家扫地机改造拖地功能了&#xff0c;…

Spring Cloud —— Gateway 服务网关

导航一、什么是服务网关二、业界常见网关组件三、Spring Cloud Gateway四、Gateway 快速入门4.1 创建 gateway 服务4.2 添加 gateway 依赖和 nacos 依赖4.3 配置路由信息4.4 测试路由转发五、Gateway 执行流程六、Gateway 断言6.1 内置路由断言工厂6.2 自定义路由断言工厂七、G…

图形显卡_选核芯显卡还是独立显卡?这才是决定笔记本电脑性能的关键

买笔记本电脑的时候&#xff0c;选核芯显卡还是独立显卡是很多朋友纠结的问题。核芯显卡是建立在和处理器同一内核芯片上的图形处理单元&#xff0c;而独立显卡拥有单独的图形核心和独立的显存。那么具体哪个更好呢&#xff1f;这里就来介绍一下。两者各自的特点核芯显卡和传统…

Spring Cloud —— 链路追踪技术

导航一、什么是链路追踪二、Spring Cloud Sleuth2.1 相关概念三、Sleuth 入门案例四、Zipkin 的集成4.1 Zipkin 介绍4.2 Zipkin 服务端安装4.3 Zipkin 客户端安装五、Zipkin 数据持久化5.1 MySQL 数据持久化5.2 Elasticsearch 数据持久化一、什么是链路追踪 在大型系统的微服务…

bool类型数组转换成一个整数_「PHP」常用的数组键值操作函数,面试重点

数组键值操作函数1、array_values ( array $array ) : array返回数组中所有的值的数组$a[name>jikeshiguangji,age>26];print_r(array_values($a));运行结果&#xff1a;$aarray("name">"jikeshiguangji","age">"26");pri…

Spring Cloud —— 消息队列与 RocketMQ

导航一、什么是 MQ二、常见的 MQ 产品三、RocketMQ 概念与架构设计3.1 基本概念1、消息模型&#xff08;Message Model&#xff09;2、生产者与消费者&#xff08;Producer & Consumer&#xff09;3、主题&#xff08;Topic&#xff09;4、代理服务器与名称服务&#xff08…

惠普打印机只打印一半_惠普打印机如何安装 惠普打印机加墨方法【介绍】

对于多数上班族和学生党来说&#xff0c;平时办公和学习不仅仅离不开 电脑 &#xff0c;与此同时还需要 打印机 起到辅助作用。目前市场上的打印机品牌较多&#xff0c;惠普就是其中知名度较高的一个牌子&#xff0c;拥有大批的消费群体。但是有些人在将打印机买回来之后&#…

Spring Cloud —— RocketMQ 的消息类型

导航引言一、普通消息1.1 可靠同步发送1.2 可靠异步发送1.3 单向发送二、顺序消息三、事务消息3.1 什么是事务消息3.2 事务消息示例1、编写本地事务逻辑2、发送半事务消息3、注册本地事务监听器4、测试引言 本文承接《Spring Cloud —— 消息队列与 RocketMQ》 RocketMQ 提供…

城市运行一网统管_全国率先!“一屏观天下、一网管全城”,临港城市运行“一网统管”平台启动建设...

景区里是否出现了大客流&#xff1f;渣土车是否有违规&#xff1f;工地上有没有安全隐患&#xff1f;……8月12日&#xff0c;临港新片区城市运行“一网统管”平台正式启动建设&#xff0c;临港新片区城市运行“一网统管”中长期规划也正式发布&#xff0c;通过构建具有临港新片…

Spring Cloud Alibaba —— Nacos Config 配置中心

导航引言一、什么是配置中心二、常见的配置中心组件三、Nacos Config 入门四、Nacos Config 动态配置4.1 硬编码方式&#xff08;默认支持动态生效&#xff09;4.2 属性注入五、配置共享5.1 相同微服务不同环境间共享5.2 不同微服务配置共享六、Nacos Config 的几个概念总结引言…

codesys com库_CODESYS在线库,酷德网镜像站启用

近期由于国内网络问题&#xff0c;造成 stroe.codesys.com 网站无法访问。在线库无法下载。为了不影响广大CODESYS用户的正常使用&#xff0c;酷德网建立stroe.codesys.com的国内镜像站:主站&#xff1a; https://store.hicodesys.com:8421/CODESYSLibs/备用站&#xff1a; …