首页 > 其他分享 >必须G1垃圾收集器

必须G1垃圾收集器

时间:2024-11-19 17:46:48浏览次数:3  
标签:G1 收集器 对象 Region 回收 垃圾 内存

G1

你们项目用了什么垃圾收集器?

我们线上采用了设计比较优秀的G1垃圾收集器,因为它不仅满足我们低停顿的要求,而且解决了CMS的浮动垃圾问题、内存碎片问题

Garbage First(简称G1)收集器开创了局部收集的设计思路和基于Region的内存布局形式。

虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异。以前的收集器分代是划分新生代、老年代、持久代(永久代)等。

G1把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。收集器能够对扮演不同角色的Region采用不同的策略去处理。

在 G1 中,当一个对象的大小超过了一定阈值时,就会被认定为大对象(Humongous Object)。这个阈值通常是一个 Region 大小的 50%,其大小可以是多个普通 Region 大小的总和

分为若干Region有以下优势:

更精细的控制(避免直接回收一整个堆内存,只回收需要的Region)、可预测的停顿时间(可以设置STW时长,选择性回收能够在这个时长内回收的区域)、内存碎片的控制(标记整理)、优先级处理

G1有效地避免了收集整个堆,通过若干个Region集进行收集,同时维护一个优先级列表,跟踪各个Region回收的“价值,优先收集价值高的Region。

这种划分很多个区域,就适合适用于大内存、多核处理器的应用场景,不然优势并不明显。

G1收集器的运行过程大致可划分为以下四个步骤:

初始标记(initial mark),标记了从GC Root开始直接关联可达的对象。STW(Stop the World)执行。

并发标记(concurrent marking),和用户线程并发执行,从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象。(和CMS一样,三色标记,异步标记,不会STW)

最终标记(Remark),也会造成STW,标记再并发标记过程中产生的垃圾。也就是重新标记(标记的范围更小)

筛选回收(Live Data Counting And Evacuation),制定回收计划,选择多个Region 构成回收集,把回收集中Region的存活对象复制到空的Region中,再清理掉整个旧 Region的全部空间。需要STW。

G1收集器运行示意图

G1垃圾收集器中的Rset和Cset

在 G1 垃圾收集器中,Rset(Remembered Set,记忆集)和 Cset(Collection Set,收集集合)是两个非常重要的概念,它们在 G1 的垃圾回收过程及内存管理中起着关键作用,以下为你详细介绍:

Rset(Remembered Set,记忆集)

简单来说,每个Region各有一个,记录外部指向本Region对象引用的抽象数据结构(对象引用信息),方便后续快速知晓跨区域引用情况

1. 定义与作用

Rset 是一种用于记录外部指向本区域(Region)对象引用的抽象数据结构。在 G1 的区域化内存布局下(将 Java 堆划分为多个大小相等的独立 Region),为了高效地判断对象的存活状态以及进行垃圾回收,需要知道哪些外部 Region 中的对象引用了本 Region 内的对象,Rset 就承担了这个记录的功能。

例如,假设有 Region A、Region B 和 Region C,Region A 中的某个对象被 Region B 中的对象引用了,那么在 Region A 的 Rset 中就会记录下这个来自 Region B 的引用信息,以便后续垃圾回收相关操作能快速知晓存在这样的跨区域引用情况。

2. 具体实现方式

在实际实现中,Rset 通常是通过卡表(Card Table)等方式来间接实现的。卡表将整个堆内存空间划分为一个个固定大小的 “卡页”(一般来说,一个卡页会对应多个连续的字节),每个卡页会对应一个标记位,用于标识这个卡页内的对象是否存在跨区域引用。当某个卡页内的对象出现跨区域引用变化时,对应的标记位就会被更新,以此来反映跨区域引用情况的改变。

例如,一个卡页覆盖了内存中某几个连续字节范围的对象,如果其中有对象被外部 Region 的对象引用了,那么这个卡页对应的标记位就会被设置为表示有跨区域引用的状态,后续垃圾回收时就能通过检查这些标记位快速定位到有跨区域引用的对象所在区域。

3. 对垃圾回收的帮助

  • 加速并发标记过程:在并发标记阶段,垃圾回收线程需要遍历对象引用关系来标记存活对象。有了 Rset,就可以快速定位到哪些本 Region 内的对象可能被外部区域引用,无需遍历整个堆内存,只需重点关注那些在 Rset 中记录的有外部引用的对象即可,大大提高了标记的效率,减少了不必要的遍历开销,同时也使得标记过程能更精准地聚焦在可能存活的对象上,提高标记准确性。

  • 精准判断对象存活状态:在判断一个 Region 内的对象是否存活时,不能仅仅依据本 Region 内的引用情况,还得考虑外部 Region 的引用。Rset 提供了一种便捷的方式来获取这些外部引用信息,使得在回收决策(比如确定某个 Region 是否可以被回收等)时,能够更全面、准确地判断对象的存活状态,避免误回收仍被外部引用的对象。

Cset(Collection Set,收集集合)

简单来说,确定要进行回收操作的一组 Region 的集合。

1. 定义与作用

Cset 是指在一次垃圾回收过程中,确定要进行回收操作的一组 Region 的集合。G1 垃圾收集器并不是每次都对整个 Java 堆的所有 Region 进行回收,而是根据一定的规则和策略,选择一部分 Region 组成 Cset,然后对这些选定的 Region 进行垃圾回收操作,比如回收其中的垃圾对象、整理内存空间等。

例如,在一次混合回收(Mixed GC)中,G1 会综合考虑各个 Region 中存活对象的数量、大小、分布情况以及设定的可预测停顿时间目标等因素,选出若干个 Region 组成 Cset,可能这些 Region 包含了部分老年代的 Region 以及一些年轻代的 Region,然后针对这个 Cset 中的 Region 开展具体的回收工作。

2. 确定原则与方式

  • 基于停顿时间目标:G1 的一个重要特性是可预测的停顿时间,使用者可以通过参数(如 -XX:MaxGCPauseMillis)设定期望的最大停顿时间。在确定 Cset 时,会优先选择那些回收后能获得较大收益(比如存活对象少、可回收空间大)且回收操作对停顿时间影响较小的 Region 加入到 Cset 中,以此来尽量满足停顿时间的要求,同时提高内存回收效率。

  • 结合存活对象情况:通过之前的标记阶段(如并发标记等)得到各个 Region 内的存活对象信息后,会统计分析每个 Region 中存活对象所占比例、数量等数据,优先挑选存活对象比例较低、数量较少的 Region 进入 Cset,因为这样的 Region 回收后能腾出较多的空闲空间,而且回收成本相对较低,有助于优化内存空间利用和整体的垃圾回收效果。

3. 对垃圾回收的意义

  • 实现高效回收与停顿控制:通过精心选择 Cset,G1 可以在满足应用对停顿时间要求的同时,有针对性地对部分需要回收的 Region 进行操作,避免了对整个堆进行全面回收带来的长时间停顿以及不必要的资源浪费,实现了高效的内存回收与可预测的停顿时间管理,提高了应用程序运行过程中的性能和响应性。

  • 优化内存空间利用:Cset 的选择是基于对内存空间中各个 Region 的存活对象等情况的细致分析,将那些最适合回收的 Region 纳入其中,经过回收操作后,可以有效地腾出空闲空间,减少内存碎片化,使得内存空间能持续保持较好的可利用状态,满足后续新对象的分配需求以及整个 Java 堆内存的健康运转。

综上所述,Rset 和 Cset 在 G1 垃圾收集器中分别从不同角度辅助和优化垃圾回收过程,Rset 侧重于记录跨区域引用以准确判断对象存活状态,Cset 则聚焦于选择合适的 Region 集合进行高效回收并控制停顿时间,二者共同助力 G1 实现其高效、可预测的内存管理目标。

有了CMS,为什么还要引入G1?

优点:CMS最主要的优点在名字上已经体现出来——并发收集、低停顿。

缺点:CMS同样有三个明显的缺点。

●Mark Sweep(标记清除)算法会导致内存碎片比较多

●CMS的并发能力比较依赖于CPU资源,并发回收时垃圾收集线程可能会抢占用户线程的资源,导致用户程序性能下降。

●最后一个阶段并发清除阶段,用户线程依然在运行,会产生所谓的理“浮动垃圾” (Floating Garbage),本次垃圾收集无法处理浮动垃圾,必须到下一次垃圾收集才能处理。如果浮动垃圾太多,会触发新的垃圾回收,导致性能降低。

G1主要解决了内存碎片过多的问题。

G1中存储大内存对象

1. 大对象的判定及处理原则

在 G1 中,当一个对象的大小超过了一定阈值时,就会被认定为大对象(Humongous Object)。这个阈值通常是一个 Region 大小的 50%,例如,如果 Region 的大小被设置为 2MB,那么大小超过 1MB 的对象就会被当作大对象来处理。

对于大对象,G1 不会将其分配到常规的年轻代或者老年代的 Region 中(即便该对象属于年轻代或者老年代对象的范畴),而是专门分配到一组连续的 Humongous Region (大对象区)中进行存储。

2. Humongous Region 的特点及分配方式

  • 特点

    • Humongous Region 同样也是从 Java 堆划分出来的独立区域,和其他普通的 Region 在本质上是一样的,只是用途上专门用来放置大对象。其大小可以是多个普通 Region 大小的总和,比如一个大对象可能占用 2 个、3 个甚至更多个 Region 的空间,具体取决于大对象自身的大小。

    • Humongous Region 在内存布局上和其他 Region 相邻,它们共同构成了 G1 的区域化内存结构,只不过在垃圾收集等处理过程中,会对其有特殊的考量。

  • 分配方式

    • 当需要分配大对象时,G1 会首先查找是否有连续的、足够大小的空闲 Humongous Region 来容纳该对象。如果有合适的空闲区域,就会把大对象分配到这些区域中;如果当前没有足够的连续空闲区域,G1 可能会触发垃圾收集动作(比如一次 Young GC 或者 Mixed GC)来尝试腾出足够的空间,回收那些不再使用的 Region,然后再进行大对象的分配。

3. 对垃圾收集的影响

  • 回收策略:

    • 在进行垃圾收集时,Humongous Region 的回收方式和普通老年代 Region 的回收方式有相似之处,也会综合运用多种算法,比如标记 - 清除、复制等算法来进行处理。不过,由于大对象本身占用空间大,其回收的收益(如果能成功回收腾出空间)或者对垃圾收集停顿时间的影响(如果回收耗时较长)都会比较显著。

    • 在筛选回收(Live Data Counting and Evacuation)阶段,G1 会根据大对象所在的 Humongous Region 中存活对象的情况(比如存活对象数量、整体存活数据量占比等因素),来决定是否对该区域进行回收以及采用何种具体的回收策略。如果一个 Humongous Region 中大部分对象都已经死亡(不再被引用),那么优先回收该区域就可能获得较大的可回收空间,有助于满足停顿时间目标以及内存空间整理需求。

  • 停顿时间关联:

    • 因为大对象的回收处理相对复杂且耗时,G1 在试图满足设定的最大停顿时间(通过-XX:MaxGCPauseMillis参数设定)目标时,需要谨慎权衡对 Humongous Region 的回收操作。例如,如果一次垃圾收集既要处理常规的年轻代、老年代 Region 回收,又要处理多个大对象所在的 Humongous Region 回收,那么就需要合理安排回收的顺序和资源分配,避免因大对象回收导致停顿时间过长,影响应用的性能和响应性。

总之,G1 通过专门划分 Humongous Region 来处理大对象,在内存分配、垃圾收集等环节都针对大对象的特点制定了相应的规则和策略,以此来确保在区域化的内存布局下能够高效地管理大内存对象,同时维持整体垃圾收集的效率和可预测的停顿时间。

标签:G1,收集器,对象,Region,回收,垃圾,内存
From: https://blog.csdn.net/qq_62097431/article/details/143820775

相关文章

  • 现场可编程门阵列英特尔® Stratix® 10 GX FPGA 1SG166HN2F43E2LG设计用于满足高吞吐
    英特尔®Stratix®10GXFPGA包含多达1020万个LE。它们在单独的收发器块上配备多达96个通用收发器,可提供2666MbpsDDR4外部内存接口性能。这些收发器可提供高达28.3Gbps的短距离和跨背板传输。这些设备针对需要最高收发器带宽和核心结构性能的FPGA应用而优化。优......
  • ENGG1110 gameplay Elaborated
    ENGG1110ProjectChangelog Rev.DateDescriptionv1.22024/11/11P.10[5.22(b)]FixedPrintouttypoofprintGameBoard()P.13[5.5.1.1/candiesinfirstround.P.14[5.5.2]AddedthecheckingofemptycellsforTargetcellatswap.P.14[5.5.4]Addedclarification......
  • 浏览器什么时候会触发垃圾回收
    浏览器触发垃圾回收(GC)的时机通常是由其内部的垃圾回收机制自动决定的,这些机制旨在优化内存使用和性能。以下是一些常见的触发垃圾回收的时机:内存使用达到阈值:浏览器会设定一个内存使用的阈值,当应用程序或网页使用的内存达到或超过这个阈值时,浏览器可能会触发垃圾回收以释放不再......
  • node.js毕设生活垃圾识别与处理系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于生活垃圾识别与处理系统的研究,现有研究主要以垃圾的单一处理环节(如仅分类或仅处理技术)为主,专门针对集成识别与处理且结合用户激励机制(如积分奖励等......
  • Python 潮流周刊#77:Python 依赖管理就像垃圾场火灾?(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。分享了12篇文章,12个开源项目,2则热门讨论,全文2200字。以下是本期摘要:......
  • 深入理解 JVM 垃圾回收算法
    前言上一篇我们对JVM的垃圾回收进行了探讨,知道了什么样的对象是垃圾对象,以及JVM虚拟机是如何判断一个对象垃圾对象的,本篇我们来探讨一下JVM垃圾回收算法。JVM系列文章传送门初识JVM(Java虚拟机)深入理解JVM(Java虚拟机)一文搞懂JVM垃圾回收(JVMGC)JVM有哪些垃......
  • JVM内存以及垃圾回收
    JVM基本概念线程JVM内存区域程序计数器(线程私有)虚拟机栈(线程私有)本地方法区(线程私有)堆(Heap-线程共享)-运行时数据区方法区/永久代(线程共享)JVM运行时内存新生代Eden区ServivorFromServivorToMinorGC的过程(复制->清空->互换)eden、ServivorFrom复制到ServivorTo,年龄+1清空......
  • pg16源码部署
    环境:OS:Centos7pg:pg16说明:pg16已经不提供在centos7下使用yum方式安装了,只能通过源码编译的方式安装.1.源码下载:https://www.postgresql.org/ftp/source/v16.4/ 2.解压源码包[root@localhostsoft]#cd/soft/pg16[root@localhostpg16]#tar-zxvfpostgresql-16.4.tar......
  • L4 垃圾邮件数据集分类延申 - NB/KNN/SVC/随机森林
    目录背景代码1.数据准备-1阶段2.数据探索3.数据准备-2阶段4.矢量化(向量化)5. 建立模型6.模型评价模型评价1.分别评价2.总体评价背景基于前文 (《【机器学习】Lesson4-朴素贝叶斯(NB)文本分类》)对于垃圾邮件数据集的分类处理,增加K邻居分类器(KNN)/支持向量......
  • 智慧园区算法视频分析服务器垃圾桶溢满园区算法详解及应用
    在数字化转型的浪潮中,视频监控技术已成为各行各业提升安全管理、优化运营效率的重要工具。特别是对于城管、环卫、教育、水利、园区、小区等多样化的应用场景,一个集成化、智能化的视频监控解决方案显得尤为关键。智慧园区算法视频分析服务器不仅能够提供高清视频监控接入,还能进行......