欢迎光临
我们一直在努力

深入理解CMS&G1垃圾回收器

在Java中,垃圾回收器是自动管理内存的重要工具。垃圾回收器有很多种,其中CMS垃圾回收器和G1垃圾回收器又是其中重要的两种类型,下面我主要讲下这两种垃圾回收器:

CMS垃圾回收器

CMS(Concurrent Mark Sweep)垃圾回收器是Java HotSpot虚拟机中的一个重要组件,是第一款真正意义上的并发回收器,实现了垃圾收集器与用户线程同时工作。以下将深入解析CMS垃圾回收器的工作原理,以及如何通过调整参数来优化其性能。

核心概念:三色标记法

三色标记将堆中对象分为三类,代表不同的扫描进度:

  • ‌黑色‌:已被 GC 访问过,且其所有引用对象也均已扫描完毕。代表确认存活的对象,GC 不再重新扫描,同时黑色对象不可能直接指向白色对象

  • ‌灰色‌:已被 GC 访问过,但其引用的子对象尚未全部扫描完毕。它是 GC 线程当前待处理的任务队列。

  • ‌白色‌:尚未被 GC 访问过的对象。在刚刚分析可达性开始的时候,所有对象会被标记为白色,但是若标记结束后仍为白色,则判定为不可达(垃圾),可被回收。

1、工作流程

1.1、初始标记阶段(initiate Mark Phase)

在初始标记阶段,会通过根节点引用查找方法,把所有有关联的对象都标记出来。这个是STW(stop-the-world ),会暂停应用程序的运行。这时采用的标记方法是三色标记方法

1.2、并发标记阶段(Concurrent Mark Phase)

在这个阶段,在应用程序运行的同时,会对堆内存的对象进行标记出来,这个阶段是并发的,不会影响程序的运行

这个阶段可能会产生两种问题:漏标或多标

漏标:灰色对象断开对白色对象的引用,同时黑色对象新增对该白色对象的引用。由于黑色对象不再扫描,白色对象会被误判为垃圾

CMS解决方案是增量更新:

  •  通过‌写屏障‌记录黑色对象新增的指向白色对象的引用

  • 在重新标记阶段,将这些黑色对象重新置为‌灰色‌,并再次扫描其引用,确保白色对象被正确标记为存活

1.3、重新标记阶段(Remark Phase)

在这个阶段,修正并发标记阶段可能错误的标记。这个阶段会触发Stop-The-World事件,但时间较短。

1.4、清理阶段(sweep Phase)

在这个阶段,包括清理和重置线程,期间会释放未被标记的对象所占用的内存,这个阶段也是并发的,不影响程序的运行

2、参数调优

2.1、调整参数 -XX:+UseCMSCompactAtFullCollection和-XX:CMSFullGCsBeforeCompaction

        使用参数-XX:+UseCMSCompactAtFullCollection可以开启压缩整理阶段,以减少内存碎片和提高内存利用率。使用参数-XX:CMSFullGCsBeforeCompaction可以设置在执行多少次Full GC后执行一次压缩整理。这两个参数可以根据实际情况进行调整。

2.2、调整内存大小 -Xmx和-Xms

        调整参数-Xmx和-Xms可以控制Java堆的最大和初始内存大小。如果堆内存过小,可能会导致频繁的Full GC,影响应用的性能。因此,需要根据实际情况调整这两个参数的大小。

2.3、避免大对象直接进入老年代 -XX:+UseLargePages

使用参数-XX:+UseLargePages可以避免大对象直接进入老年代,从而减少Full GC的频率。这个参数适用于有大量大对象的场景。

2.4、分析堆转储(Heap Dump)和垃圾回收日志(GC Log)

分析堆转储和垃圾回收日志可以帮助我们找到内存泄漏和频繁Full GC的原因。通过分析这些日志,我们可以更好地了解应用的内存使用情况,并进行针对性的优化。

3、特点&缺点

3.1 在初始标记和重新标记阶段,CMS会暂停应用程序的运行

3.2 CMS对老年代的清理不够彻底,可能会导致老年代中存在大量的空闲空间

G1 

G1(Garbage-First) 是一款面向服务端应用的垃圾收集器,主要针对配备多核CPU及大容量内存的机器,以极高概率满足GC停顿时间的同时,还兼具高吞吐量的性能特征。

重要概念:分区Region

  • 使用G1收集器时,他将整个Java推划分成2048个大小相同的独立Region块,每个Region块大小根据推空间的实际大小而定的,单个Region被控制在1MB到32MB之间,并且是2的N次幂,即1、2、4、8、16、32MB。通过参数-XX:G1HeapRegionSize设定。所有的Region大小相同,且在JVM生命周期内不会改变。

  • 虽然保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,他们都一部分Region(不需要连续)的集合。通过Region的动态分配方

  • 一个Region有可能属于Eden、survivor或者Old区,但是一个Region只可能属于一个角色。图中E代表Eden,S代表Survivor,O代表Old。空白表示未使用区域。

  • G1还新增加了一种新的内存区域H,叫做Humongous区域,图中H块,主要存储大对象,如果对象超过1.5个region,就放到H

  • 1、工作流程

    1.1 初始标记(Initial Marking Phase)

    这个过程也是通过根节点引用方式找出所有可达的对象,速度是非常快的,但是也是停止应用程序,有stw(stop-the-world),

    1.2 并发标记(Concurrent Mark Phase)

    在初始标记完,进入并发标记阶段,这个过程中是不会停止应用程序的,会通过递归的方式进一步把所有的可达对象都标记出来

    1.3 最终标记(final Mark Phase)

    为了处理在并发标记过程中新产生的对象引用关系,G1 GC会执行一次短暂的STW的最终标记。这个阶段确保所有在并发标记阶段漏掉的对象都被正确标记

    1.4 筛选回收(Live Data Counting and Evacuation)

    在这个阶段,G1 GC会根据每个Region的垃圾堆积情况和回收价值进行排序,并选择性地回收部分Region中的垃圾对象。回收过程包括将存活的对象从一个Region复制或移动到另一个Region,并更新相关的引用。这个过程也是并发的,旨在最大限度地减少停顿时间。同时,这个阶段可能会涉及到对象的整理和压缩,以减少内存碎片

    2、参数调优

    2.1、-XX:+UseG1GC:启用G1垃圾收集器

    2.2、-XX:G1HeapRegionSize:设置每个region的大小。

    2.3、-XX:MaxGCPauseMillis:这个是期望GC最大停顿的时间。

    2.4、-XX:InitiatingHeapOccupancyPercent: 这个参数用于设置触发并发GC周期的Java堆占用率阈值,当堆内存达到这个数值,则启动回收机制。

    3、特点&缺点

    3.1、可预测的停顿时间,高效的内存回收,优化内存分配

    3.2、对硬件要求比较高,适合大内存的服务。

    赞(0)
    未经允许不得转载:171主机测评 » 深入理解CMS&G1垃圾回收器
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址