深入剖析 JVM 垃圾收集器之 CMS 和 G1

ops/2025/2/11 14:12:20/

在 Java 虚拟机(JVM)的世界里,垃圾收集器是一个至关重要的组件,它负责自动回收不再被使用的内存空间,保证应用程序的稳定运行。本文将着重介绍两种具有代表性的垃圾收集器:CMS(Concurrent Mark Sweep)收集器和 G1(Garbage-First)收集器。

CMS 收集器

基本原理

CMS 收集器是一种以获取最短回收停顿时间为目标的收集器。它的工作过程主要分为以下几个阶段:

  1. 初始标记(Initial Mark): 暂停所有的应用线程,标记出所有 GC Roots 能直接关联到的对象。这个阶段速度很快,但会导致应用短暂停顿。
  2. 并发标记(Concurrent Mark): 与应用程序线程并发执行,从 GC Roots 的直接关联对象开始遍历整个对象图,标记出所有可达对象。这个阶段不会停顿应用线程,但耗时较长。
  3. 重新标记(Remark): 暂停应用线程,修正并发标记期间因应用程序继续运行而导致标记产生变动的那一部分对象的标记记录。停顿时间比初始标记稍长,但远比并发标记短。
  4. 并发清除(Concurrent Sweep): 与应用程序线程并发执行,清除掉标记为不可达的对象所占用的内存空间。

特点

  • 优点:并发收集、低停顿,能较好地满足对响应时间要求较高的应用场景。
  • 缺点
    • 对 CPU 资源非常敏感,在并发阶段会占用一部分 CPU 资源,导致应用程序性能下降。
    • 无法处理浮动垃圾(Floating Garbage),可能出现 “Concurrent Mode Failure” 失败进而触发 Full GC。
    • 采用标记 - 清除算法,会产生内存碎片,当碎片过多时,可能会提前触发 Full GC。

适用场景

适用于注重响应时间,并且应用程序运行过程中产生的垃圾对象不是特别多的场景,比如互联网电商的交易系统、在线支付系统等。

G1 收集器

基本原理

G1 收集器是一种面向服务器的垃圾收集器,它将整个 Java 堆划分为多个大小相等的独立区域(Region),并跟踪各个 Region 里面的垃圾堆积程度,在后台维护一个优先列表,每次根据允许的收集时间,优先回收垃圾最多的 Region。它的工作过程主要包括:

  1. 初始标记(Initial Mark): 暂停应用线程,标记出 GC Roots 能直接关联到的对象,并且修改 TAMS(Top at Mark Start)的值,让下一阶段用户程序并发运行时,能正确地在可用的 Region 中分配新对象。
  2. 并发标记(Concurrent Mark): 与应用程序线程并发执行,从 GC Roots 开始对堆中对象进行可达性分析,标记出所有可达对象。
  3. 最终标记(Final Mark): 暂停应用线程,处理并发标记阶段结束后仍遗留下来的少量 SATB(Snapshot-At-The-Beginning)记录。
  4. 筛选回收(Live Data Counting and Evacuation): 首先对各个 Region 中的存活对象进行统计,然后根据用户期望的停顿时间来制定回收计划,回收价值最大的 Region(这些 Region 中包含的垃圾对象最多)。回收过程中采用复制算法,将一个 Region 中的存活对象复制到另一个 Region 中,从而避免了内存碎片的产生。

特点

  • 优点
    • 并行与并发:G1 能充分利用多 CPU、多核环境下的硬件优势,使用多个 CPU 来缩短 Stop-The-World 停顿时间。部分其他收集器原本需要停顿 Java 线程执行的 GC 动作,G1 收集器仍然可以通过并发的方式让 Java 程序继续执行。
    • 分代收集:虽然 G1 可以不需要其他收集器配合就能独立管理整个 GC 堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次 GC 的旧对象,这仍然是一种分代的概念。
    • 空间整合:G1 从整体来看是基于 “标记 - 整理” 算法实现的收集器,从局部(两个 Region 之间)上来看是基于 “复制” 算法实现的,这两种算法都意味着 G1 运行期间不会产生内存碎片,垃圾收集完成之后能提供规整的可用内存。
    • 可预测的停顿:G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。
  • 缺点
    • 相比其他垃圾收集器,G1 在垃圾回收过程中产生的内存占用(Footprint)和程序运行时的额外执行负载(Overload)可能会高一些。
    • 由于 G1 的算法较为复杂,在实现和调优方面对开发者的要求相对较高。

适用场景

适用于大内存、多核 CPU 的服务器环境,并且应用程序对停顿时间有比较严格要求的场景,如大规模的电商平台、金融交易系统等。

CMS 与 G1 收集器对比

  1. 停顿时间:CMS 以获取最短回收停顿时间为目标,但在高并发情况下可能出现较长停顿;G1 能建立可预测的停顿时间模型,在大内存情况下,停顿时间通常比 CMS 更可控。
  2. 内存管理:CMS 采用标记 - 清除算法,容易产生内存碎片;G1 采用标记 - 整理和复制算法,避免了内存碎片问题。
  3. CPU 资源占用:CMS 在并发阶段对 CPU 资源非常敏感,会影响应用程序性能;G1 虽然也会占用一定 CPU 资源,但由于其并行和并发的特点,在多核环境下能更好地利用 CPU 资源。
  4. 适用场景:CMS 适用于响应时间要求高、垃圾产生量相对较少的场景;G1 适用于大内存、对停顿时间有严格要求的场景。

CMS 和 G1 收集器都有各自的特点和适用场景,在实际应用中,我们需要根据应用程序的特点和需求来选择合适的垃圾收集器,以达到最佳的性能表现。同时,随着 JVM 技术的不断发展,垃圾收集器也在持续演进,未来有望出现更高效、更智能的垃圾收集器。


http://www.ppmy.cn/ops/157539.html

相关文章

【含文档+PPT+源码】基于微信小程序的校园志愿者管理系统的设计与实现

项目介绍 本课程演示的是一款 基于微信小程序的校园志愿者管理系统的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…

在线SQL转JSON-GO在线工具集

此工具提供多数据库 SQL 自动转换为 JSON 格式的工具,支持 MySQL、PostgreSQL、Oracle 等主流数据库。此工具将 SQL 查询结果转换为结构化的 JSON 数据,方便 JSON 处理和数据交换,优化数据管理和集成过程,提升工作效率。 gotool

【文本处理】如何在批量WORD和txt文本提取手机号码,固话号码,提取邮箱,删除中文,删除英文,提取车牌号等等一些文本提取固定格式的操作,基于WPF的解决方案

企业的应用场景 数据清洗:在进行数据导入或分析之前,往往需要对大量文本数据进行预处理,比如去除文本中的无关字符(中文、英文),只保留需要的联系信息(手机号码、固话号码、邮箱)。…

【JVM详解二】常量池

一、常量池概述 JVM的常量池主要有以下几种: class文件常量池运行时常量池字符串常量池基本类型包装类常量池 它们相互之间关系大致如下图所示: 每个 class 的字节码文件中都有一个常量池,里面是编译后即知的该 class 会用到的字面量与符号引…

【STM32H743】【RT-Thread Studio】RTC功能(基于BSP工程可一键开启)

前言 之前建立了文件系统,可是使用mkfs格式化SD卡时会报没有RTC错误,原因是FATFS文件系统需要时间戳 现在给系统加入RTC功能 环境 1、ATK-STM32H743-APOLLO开发板 2、RT-Thread Studio 3、基于BSP建立工程 BSP设置 下载验证 在RT-Thread Studio中开…

【深度学习】突破数据局限:少样本图像数据的特征提取实战攻略

在进行深度图像处理时最重要的一步往往是图像特征提取检测,尤其是样本特征较少时,接下来我们以人脸识别之舌头识别为例,来讲解一下少数据样本时常用的五种图像数据特征提取的方法。 在构建舌头识别模型时,当样本数据量较少的情况…

畅游Diffusion数字人(16):由音乐驱动跳舞视频生成

畅游Diffusion数字人(0):专栏文章导航 前言:从Pose到跳舞视频生成的工作非常多,但是还没有直接从音乐驱动生成的工作。最近字节跳动提出了MuseDance,无需复杂的动作引导输入(如姿势或深度序列),从而使不同专业水平的用户都能轻松进行灵活且富有创意的视频生成。 目录 贡…

DeepSeek和ChatGPT的优劣或者区别(答案来DeepSeek和ChatGPT)

DeepSeek的答案 DeepSeek与ChatGPT作为当前两大主流AI模型,在架构设计、性能表现、应用场景等方面存在显著差异,以下从多个维度进行对比分析: 一、架构与训练效率 架构设计 DeepSeek:采用混合专家(MoE)框架…