当前位置: 首页 > news >正文

JVM之垃圾回收器G1概述的详细解析

G1(并发)
G1 特点

G1(Garbage-First)是一款面向服务端应用的垃圾收集器,应用于新生代和老年代、采用标记-整理算法、软实时、低延迟、可设定目标(最大 STW 停顿时间)的垃圾回收器,用于代替 CMS,适用于较大的堆(>4 ~ 6G),在 JDK9 之后默认使用 G1

G1 对比其他处理器的优点:

  • 并发与并行:

    • 并行性:G1 在回收期间,可以有多个 GC 线程同时工作,有效利用多核计算能力,此时用户线程 STW

    • 并发性:G1 拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此不会在整个回收阶段发生完全阻塞应用程序的情况

    • 其他的垃圾收集器使用内置的 JVM 线程执行 GC 的多线程操作,而 G1 GC 可以采用应用线程承担后台运行的 GC 工作,JVM 的 GC 线程处理速度慢时,系统会调用应用程序线程加速垃圾回收过程

  • 分区算法

    • 从分代上看,G1 属于分代型垃圾回收器,区分年轻代和老年代,年轻代依然有 Eden 区和 Survivor 区。从堆结构上看,新生代和老年代不再物理隔离,不用担心每个代内存是否足够,这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次 GC

    • 将整个堆划分成约 2048 个大小相同的独立 Region 块,每个 Region 块大小根据堆空间的实际大小而定,整体被控制在 1MB 到 32 MB之间且为 2 的 N 次幂,所有 Region 大小相同,在 JVM 生命周期内不会被改变。G1 把堆划分成多个大小相等的独立区域,使得每个小空间可以单独进行垃圾回收

    • 新的区域 Humongous:本身属于老年代区,当出现了一个巨型对象超出了分区容量的一半,该对象就会进入到该区域。如果一个 H 区装不下一个巨型对象,那么 G1 会寻找连续的 H 分区来存储,为了能找到连续的 H 区,有时候不得不启动 Full GC

    • G1 不会对巨型对象进行拷贝,回收时被优先考虑,G1 会跟踪老年代所有 incoming 引用,这样老年代 incoming 引用为 0 的巨型对象就可以在新生代垃圾回收时处理掉

    • Region 结构图:

  • 空间整合:

    • CMS:标记-清除算法、内存碎片、若干次 GC 后进行一次碎片整理

    • G1:整体来看是基于标记 - 整理算法实现的收集器,从局部(Region 之间)上来看是基于复制算法实现的,两种算法都可以避免内存碎片

  • 可预测的停顿时间模型(软实时 soft real-time):可以指定在 M 毫秒的时间片段内,消耗在 GC 上的时间不得超过 N 毫秒

    • 由于分块的原因,G1 可以只选取部分区域进行内存回收,这样缩小了回收的范围,对于全局停顿情况也能得到较好的控制

    • G1 跟踪各个 Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间,通过过去回收的经验获得),在后台维护一个优先列表,每次根据允许的收集时间优先回收价值最大的 Region,保证了 G1 收集器在有限的时间内可以获取尽可能高的收集效率

    • 相比于 CMS GC,G1 未必能做到 CMS 在最好情况下的延时停顿,但是最差情况要好很多

G1 垃圾收集器的缺点:

  • 相较于 CMS,G1 还不具备全方位、压倒性优势。比如在用户程序运行过程中,G1 无论是为了垃圾收集产生的内存占用还是程序运行时的额外执行负载都要比 CMS 要高

  • 从经验上来说,在小内存应用上 CMS 的表现大概率会优于 G1,而 G1 在大内存应用上则发挥其优势,平衡点在 6-8GB 之间

应用场景:

  • 面向服务端应用,针对具有大内存、多处理器的机器

  • 需要低 GC 延迟,并具有大堆的应用程序提供解决方案


记忆集

记忆集 Remembered Set 在新生代中,每个 Region 都有一个 Remembered Set,用来被哪些其他 Region 里的对象引用(谁引用了我就记录谁)

  • 程序对 Reference 类型数据写操作时,产生一个 Write Barrier 暂时中断操作,检查该对象和 Reference 类型数据是否在不同的 Region(跨代引用),不同就将相关引用信息记录到 Reference 类型所属的 Region 的 Remembered Set 之中

  • 进行内存回收时,在 GC 根节点的枚举范围中加入 Remembered Set 即可保证不对全堆扫描也不会有遗漏

垃圾收集器在新生代中建立了记忆集这样的数据结构,可以理解为它是一个抽象类,具体实现记忆集的三种方式:

  • 字长精度

  • 对象精度

  • 卡精度(卡表)

卡表(Card Table)在老年代中,是一种对记忆集的具体实现,主要定义了记忆集的记录精度、与堆内存的映射关系等,卡表中的每一个元素都对应着一块特定大小的内存块,这个内存块称之为卡页(card page),当存在跨代引用时,会将卡页标记为 dirty,JVM 对于卡页的维护也是通过写屏障的方式

收集集合 CSet 代表每次 GC 暂停时回收的一系列目标分区,在任意一次收集暂停中,CSet 所有分区都会被释放,内部存活的对象都会被转移到分配的空闲分区中。年轻代收集 CSet 只容纳年轻代分区,而混合收集会通过启发式算法,在老年代候选回收分区中,筛选出回收收益最高的分区添加到 CSet 中

卡表和操作系统内存页一个道理

  • CSet of Young Collection

  • CSet of Mix Collection


工作原理

G1 中提供了三种垃圾回收模式:YoungGC、Mixed GC 和 Full GC,在不同的条件下被触发

  • 当堆内存使用达到一定值(默认 45%)时,开始老年代并发标记过程

  • 标记完成马上开始混合回收过程

顺时针:Young GC → Young GC + Concurrent Mark → Mixed GC 顺序,进行垃圾回收

  • Young GC:发生在年轻代的 GC 算法,一般对象(除了巨型对象)都是在 eden region 中分配内存,当所有 eden region 被耗尽无法申请内存时,就会触发一次 Young GC,G1 停止应用程序的执行 STW,把活跃对象放入老年代,垃圾对象回收

    回收过程

    1. 扫描根:根引用连同 RSet 记录的外部引用作为扫描存活对象的入口

    2. 更新 RSet:处理 dirty card queue 更新 RS,此后 RSet 准确的反映对象的引用关系

      • dirty card queue:类似缓存,产生了引用先记录在这里,然后更新到 RSet

      • 作用:产生引用直接更新 RSet 需要线程同步开销很大,使用队列性能好

    3. 处理 RSet:识别被老年代对象指向的 Eden 中的对象,这些被指向的对象被认为是存活的对象,把需要回收的分区放入 Young CSet 中进行回收

    4. 复制对象:Eden 区内存段中存活的对象会被复制到 survivor 区,survivor 区内存段中存活的对象如果年龄未达阈值,年龄会加1,达到阀值会被会被复制到 old 区中空的内存分段,如果 survivor 空间不够,Eden 空间的部分数据会直接晋升到老年代空间

    5. 处理引用:处理 Soft,Weak,Phantom,JNI Weak 等引用,最终 Eden 空间的数据为空,GC 停止工作

  • Concurrent Mark

    • 初始标记:标记从根节点直接可达的对象,这个阶段是 STW 的,并且会触发一次年轻代 GC

    • 并发标记 (Concurrent Marking):在整个堆中进行并发标记(应用程序并发执行),可能被 YoungGC 中断。会计算每个区域的对象活性,即区域中存活对象的比例,若区域中的所有对象都是垃圾,则这个区域会被立即回收(实时回收),给浮动垃圾准备出更多的空间,把需要收集的 Region 放入 CSet 当中

    • 最终标记:为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程的 Remembered Set Logs 里面,最终标记阶段需要把 Remembered Set Logs 的数据合并到 Remembered Set 中,这阶段需要停顿线程,但是可并行执行(防止漏标

    • 筛选回收:并发清理阶段,首先对 CSet 中各个 Region 中的回收价值和成本进行排序,根据用户所期望的 GC 停顿时间来制定回收计划,也需要 STW

  • Mixed GC:当很多对象晋升到老年代时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即 Mixed GC,除了回收整个 young region,还会回收一部分的 old region,过程同 YGC

    注意:是一部分老年代,而不是全部老年代,可以选择哪些老年代 region 收集,对垃圾回收的时间进行控制

    在 G1 中,Mixed GC 可以通过 -XX:InitiatingHeapOccupancyPercent 设置阈值

  • Full GC:对象内存分配速度过快,Mixed GC 来不及回收,导致老年代被填满,就会触发一次 Full GC,G1 的 Full GC 算法就是单线程执行的垃圾回收,会导致异常长时间的暂停时间,需要进行不断的调优,尽可能的避免 Full GC

    产生 Full GC 的原因:

    • 晋升时没有足够的空间存放晋升的对象

    • 并发处理过程完成之前空间耗尽,浮动垃圾


相关参数
  • -XX:+UseG1GC:手动指定使用 G1 垃圾收集器执行内存回收任务

  • -XX:G1HeapRegionSize:设置每个 Region 的大小。值是 2 的幂,范围是 1MB 到 32MB 之间,目标是根据最小的 Java 堆大小划分出约 2048 个区域,默认是堆内存的 1/2000

  • -XX:MaxGCPauseMillis:设置期望达到的最大 GC 停顿时间指标,JVM会尽力实现,但不保证达到,默认值是 200ms

  • -XX:+ParallelGcThread:设置 STW 时 GC 线程数的值,最多设置为 8

  • -XX:ConcGCThreads:设置并发标记线程数,设置为并行垃圾回收线程数 ParallelGcThreads 的1/4左右

  • -XX:InitiatingHeapoccupancyPercent:设置触发并发 Mixed GC 周期的 Java 堆占用率阈值,超过此值,就触发 GC,默认值是 45

  • -XX:+ClassUnloadingWithConcurrentMark:并发标记类卸载,默认启用,所有对象都经过并发标记后,就可以知道哪些类不再被使用,当一个类加载器的所有类都不再使用,则卸载它所加载的所有类

  • -XX:G1NewSizePercent:新生代占用整个堆内存的最小百分比(默认5%)

  • -XX:G1MaxNewSizePercent:新生代占用整个堆内存的最大百分比(默认60%)

  • -XX:G1ReservePercent=10:保留内存区域,防止 to space(Survivor中的 to 区)溢出


调优

G1 的设计原则就是简化 JVM 性能调优,只需要简单的三步即可完成调优:

  1. 开启 G1 垃圾收集器

  2. 设置堆的最大内存

  3. 设置最大的停顿时间(STW)

不断调优暂停时间指标:

  • XX:MaxGCPauseMillis=x 可以设置启动应用程序暂停的时间,G1会根据这个参数选择 CSet 来满足响应时间的设置

  • 设置到 100ms 或者 200ms 都可以(不同情况下会不一样),但设置成50ms就不太合理

  • 暂停时间设置的太短,就会导致出现 G1 跟不上垃圾产生的速度,最终退化成 Full GC

  • 对这个参数的调优是一个持续的过程,逐步调整到最佳状态

不要设置新生代和老年代的大小:

  • 避免使用 -Xmn 或 -XX:NewRatio 等相关选项显式设置年轻代大小,G1 收集器在运行的时候会调整新生代和老年代的大小,从而达到我们为收集器设置的暂停时间目标

  • 设置了新生代大小相当于放弃了 G1 的自动调优,我们只需要设置整个堆内存的大小,剩下的交给 G1 自己去分配各个代的大小


相关文章:

JVM之垃圾回收器G1概述的详细解析

G1(并发) G1 特点 G1(Garbage-First)是一款面向服务端应用的垃圾收集器,应用于新生代和老年代、采用标记-整理算法、软实时、低延迟、可设定目标(最大 STW 停顿时间)的垃圾回收器,用于代替 CMS&#xff0…...

1.15寒假作业

web:nss靶场ez_ez_php 打开环境,理解代码 使用个体传参的方法,首先代码会检查file参数的前三个字符是不是php,如果是就输出nice,然后用include函数包含file,绕过不是则输出hacker,如果没有file…...

RK356x bsp 5 - 海华AW-CM358SM Wi-Fi/Bt模组调试记录

文章目录 1、环境介绍2、目标3、海华AW-CM358SM3.1、基本信息3.2、支持SDIO3.03.3、电气特性 4、适配流程步骤5、SDIO控制器适配5.1、sdio dts配置5.2、验证 6、Wi-Fi 适配6.1、wifi dts配置6.2、驱动移植6.2.1、kernel menuconfig6.2.2、传统驱动移植6.2.3、RK SDK WIFI/BT驱动…...

支持Google Analytics快捷添加的CMS:费用与部署形式详解

CMS 的费用和部署形式是选择平台的重要参考因素,不同的业务需求需要不同的解决方案。本文将从费用和部署形式两个角度,详细分析支持 Google Analytics 快捷集成的 CMS 和工具,帮助您更好地了解这些平台的特点。 1. BigCommerce 费用&#xff…...

CSS | 实现三列布局(两边边定宽 中间自适应,自适应成比)

目录 示例1 (中间自适应 示例2(中间自适应 示例3(中间自适应 示例4 (自适应成比 示例5(左中定宽,右边自适应 示例6(中间自适应 示例7(中间自适应 示例8(中间定宽…...

fpga系列 HDL:跨时钟域同步 双触发器同步器

目录 **双触发器同步器(Two-Flip-Flop Synchronizer)示例代码**:双触发器同步器的优缺点优点:缺点:适用场景: 应用实例:同步来自spi_slave的单个使能信号 跨时钟域的设计需要特别小心&#xff0…...

金融项目实战 05|Python实现接口自动化——登录接口

目录 一、代码实现自动化理论及流程 二、脚本实现的理论和准备工作 1、抽取功能转为自动化用例 2、搭建环境(测试工具) 3、搭建目录结构 三、登录接口脚本实现 1、代码编写 1️⃣api目录 2️⃣script目录 2、断言 3、参数化 1️⃣编写数据存储文件:jso…...

《HTML在网络安全中的多面应用:从防范攻击到安全审查》

Html基础 Html简介 HTML(HyperText Markup Language,超文本标记语言)是用于描述网页内容和结构的标准语言。以下是对HTML的简要介绍: 基本概念 定义: HTML不是一种编程语言,而是一种标记语言。 它使用标…...

Linux网络 | 学习传输层网络协议之UDP(短篇)

前言: 本节内容正式迈入传输层网络协议的知识殿堂, 之前的文章, 我们都是在应用层进行翻来覆去。 比如http就是应用层协议, 只不过使用了tcp的系统调用。 从本节开始, 友友们将会学习传输层两大协议: UDP和…...

iOS - 内存屏障的使用场景

内存屏障的使用是为了解决以下几个关键问题: 1. CPU 乱序执行 // 没有内存屏障时,CPU 可能乱序执行 void example() {// 这两行代码可能被 CPU 重排序a 1; // 操作1flag true; // 操作2 }// 使用内存屏障确保顺序 void safeExample() {a 1;…...

MySQL 8.0 新特性详解与实用示例

MySQL 8.0 新特性详解与实用示例 1. 引言 MySQL 8.0 是 MySQL 版本系列中具有里程碑意义的更新版本,带来了大量新功能和优化,极大地提升了数据库的性能和可用性。本文将深入介绍 MySQL 8.0 的主要新特性及其应用场景,帮助你在项目中更高效地…...

【STM32-学习笔记-5-】ADC

文章目录 ADCADC函数Ⅰ、ADC_InitTypeDef结构体参数①、ADC_Mode②、ADC_DataAlign③、ADC_ExternalTrigConv④、ADC_ContinuousConvMode⑤、ADC_ScanConvMode⑥、ADC_NbrOfChannel Ⅱ、ADC配置示例1、单次转换,非扫描单次转换非扫描模式下,获取多通道的…...

TY1801 反激变换器PWM GaN功率开关

TY1801 是一款针对离线式反激变换器的多模式 PWM GaN 功率开关。TY1801 内置 GaN 功率管,它具备超宽 的 VCC 工作范围,非常适用于 PD 快充等要求宽输出电压的应用场合,系统不需要使用额外的绕组或外围降压电路,节省系统 BOM 成本。TY1801 支持 Burst&…...

Jenkins安装、插件下载及构建环境配置详解

Jenkins简介 1.1 简介 Jenkins 是一个基于Java开发的开源持续集成工具,它提供了一个开放且易用的软件平台,主要用于自动化构建、测试和部署软件项目,以实现持续集成(CI)和持续交付/部署(CD)。…...

ESP32,uart安装驱动uart_driver_install函数剖析,以及intr_alloc_flags 参数的意义

在 uart_driver_install 函数中,参数 RX_BUF_SIZE * 2 指定了接收缓冲区(RX buffer)的大小。这个参数对于 UART 驱动程序来说非常重要,因为它决定了可以存储多少接收到的数据,直到应用程序读取它们为止。下面是对该函数…...

Ubuntu把应用程序放到桌面

有时候我们下载的软件是一个文件夹,通常需要进入进入指定文件夹下去执行.sh 文件来启动,下面来个实例如何把idea放到桌面 打开文件目录/usr/share/applications/或者~/.local/share/applications/目录。第一个目录是全局的,所有用户都可以使…...

什么是端口映射

端口映射 端口映射(Port Mapping)是一种网络技术,用于将外部网络请求转发到内部网络的特定设备或服务。它通常用于以下场景: 外部访问内部服务:允许外部用户通过公网IP访问内网中的设备或服务。多设备共享IP&#xf…...

数据结构《MapSet哈希表》

文章目录 一、搜索树1.1 定义1.2 模拟实现搜索 二、Map2.1 定义2.2 Map.Entry2.3 TreeMap的使用2.4 Map的常用方法 三、Set3.1 定义3.2 TreeSet的使用3.3 Set的常用方法 四、哈希表4.1 哈希表的概念4.2 冲突4.2.1 冲突的概念4.2.2 冲突的避免1. 选择合适的哈希函数2. 负载因子调…...

【QT】QComboBox:activated信号和currentIndexChanged信号的区别

目录 1、activated1.1 原型1.2 触发机制1.3 使用场景1.4 连接信号和槽的方法1.4.1 方式一1.4.2 方式二 2、currentIndexChanged2.1 原型2.2 触发机制2.3 使用场景2.4 连接信号和槽的方法 1、activated 1.1 原型 [signal] void QComboBox::activated(int index) [signal] void…...

【Block总结】ELGCA模块,池化-转置(PT)注意力和深度卷积有效聚合局部和全局上下文信息

ELGCA结构 论文题目:ELGC-Net: Efficient Local-Global Context Aggregation for Remote Sensing Change Detection 论文链接:https://arxiv.org/pdf/2403.17909 官方github:https://github.com/techmn/elgcnet 高效局部-全局上下文聚合器&…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

【JVM】- 内存结构

引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...