JVM 垃圾回收器

以下是对主流 JVM 垃圾回收器的详细解析,涵盖 

一、Serial GC(单线程串行回收器)

二、Parallel GC(吞吐量优先回收器)

三、CMS(Concurrent Mark Sweep,低延迟回收器)

四、G1(Garbage-First,区域分代回收器)

五、ZGC(超低延迟回收器)

六、Shenandoah(OpenJDK 低延迟回收器)

 的核心机制、适用场景及横向对比,帮助理解不同垃圾回收器的设计哲学与性能特点。

一、Serial GC(单线程串行回收器)

核心机制
  • 算法
    • 新生代:复制算法(Copying Algorithm),将存活对象从 Eden/Survivor 复制到另一块 Survivor。
    • 老年代:标记 - 整理算法(Mark-Compact),标记存活对象后压缩内存空间。
  • 执行特点
    • 单线程:GC 时需 Stop The World(STW),暂停所有应用线程,全程由一条 GC 线程完成。
    • 简单高效:无线程切换开销,适合内存较小的环境。
关键参数
-XX:+UseSerialGC        # 启用 Serial GC(默认用于 Client 模式)
-XX:SurvivorRatio=8     # Eden:Survivor 比例(默认 8:1)
适用场景
  • 嵌入式设备或 单核心服务器(如小型桌面应用)。
  • 内存 < 1GB 的场景,STW 时间可控。
优缺点
优点缺点
简单可靠,无额外内存开销单线程导致 STW 时间较长
适合内存小的场景无法利用多核 CPU 优势

二、Parallel GC(吞吐量优先回收器)

核心机制
  • 算法
    • 新生代:多线程复制算法,并行执行垃圾回收。
    • 老年代:多线程标记 - 整理算法(JDK 8 前为 Serial Old,JDK 9+ 为 Parallel Old)。
  • 执行特点
    • 多线程并行:通过 -XX:ParallelGCThreads 设置线程数,利用多核 CPU 缩短 STW 时间。
    • 目标吞吐量:通过 -XX:GCTimeRatio 控制 GC 时间占比(默认 99%,即 GC 时间 ≤ 1%)。
关键参数
-XX:+UseParallelGC      # 启用 Parallel GC(默认用于 Server 模式)
-XX:MaxGCPauseMillis=100 # 目标最大停顿时间(毫秒,动态调整堆大小)
-XX:GCTimeRatio=99      # 吞吐量目标(1/(1+N),N=99 即吞吐量 99%)
适用场景
  • 后台计算任务(如大数据处理、科学计算),优先保证吞吐量。
  • 堆内存中等大小(如 4-8GB),允许较短 STW 但需高持续处理能力。
优缺点
优点缺点
多线程提升吞吐量停顿时间仍随堆增大而增长
自动调优(自适应策略)无法满足低延迟需求

三、CMS(Concurrent Mark Sweep,低延迟回收器)

核心机制
  • 算法
    • 标记 - 清除(Mark-Sweep):老年代使用该算法,避免整理内存的 STW 开销。
    • 分代设计:新生代用 Parallel Scavenge(多线程复制),老年代用 CMS 并发回收。
  • 执行阶段(老年代):
    1. 初始标记(STW):标记根对象,耗时短。
    2. 并发标记:与应用线程并行标记可达对象。
    3. 重新标记(STW):修正并发标记期间的变动,耗时短。
    4. 并发清除:与应用线程并行清除垃圾对象。
关键参数
-XX:+UseConcMarkSweepGC  # 启用 CMS GC
-XX:CMSInitiatingOccupancyFraction=70 # 老年代占用 70% 时触发 GC
-XX:+CMSParallelRemarkEnabled # 启用并行重新标记(减少 STW 时间)
适用场景
  • 交互式应用(如 Web 服务器、前端服务),需降低 STW 对用户体验的影响。
  • 堆内存较大(如 8-16GB),但对象存活率较高(老年代占比大)。
优缺点
优点缺点
老年代并发回收,STW 时间短标记 - 清除导致内存碎片
适合低延迟场景并发阶段占用 CPU 资源
分代设计提升回收效率可能触发 "Concurrent Mode Failure"(回收速度慢于分配速度)

四、G1(Garbage-First,区域分代回收器)

核心机制
  • 分区(Region)设计
    • 将堆划分为大小相等的 Region(如 2MB-32MB),每个 Region 可动态扮演 Eden、Survivor、Old 或 Humongous(大对象)。
    • 优先回收价值高的区域:通过记录每个 Region 的垃圾占比,优先处理回收收益最大的区域(Garbage-First 得名)。
  • 算法
    • 新生代:多线程复制算法,回收 Eden/Survivor 区域。
    • 老年代:并发标记 + 混合回收(部分 Old Region + 新生代),基于标记 - 整理算法。
执行阶段
  1. 初始标记(STW):标记根对象。
  2. 并发标记:与应用线程并行标记可达对象。
  3. 最终标记(STW):处理 SATB 日志(Snapshot At The Beginning,记录并发阶段新增引用)。
  4. 筛选回收(STW):计算各 Region 回收收益,选择部分 Old Region 与新生代混合回收。
关键参数
-XX:+UseG1GC            # 启用 G1 GC
-XX:G1HeapRegionSize=4m # 设置 Region 大小(自动推算默认值)
-XX:MaxGCPauseMillis=200 # 目标最大停顿时间(默认 200ms)
-XX:G1MixedGCCountTarget=8 # 混合回收时最大 Region 数
适用场景
  • 大内存(8GB+) 且 需要兼顾吞吐量与低延迟 的场景(如微服务、中间件)。
  • 对象分配频率高(如新生代大对象多),或存在大量中等大小对象(避免进入 Humongous Region)。
优缺点
优点缺点
分区设计避免内存碎片内存占用高(每个 Region 需元数据)
可预测的停顿时间并发标记阶段耗 CPU 资源
混合回收应对老年代回收调优复杂度高于 CMS/Parallel

五、ZGC(超低延迟回收器)

核心机制
  • 着色指针(Colored Pointers)
    • 将对象引用的低 4 位用于存储 GC 状态(如标记位、重映射状态),无需修改对象头,减少内存访问开销。
  • 读屏障(Load Barrier)
    • 在读取对象引用时动态修正指针(如对象被移动到新 Region,通过读屏障获取新地址)。
  • 并发标记 - 整理
    • 全程几乎无 STW(仅初始标记和再标记有极短停顿,通常 <1ms),支持 TB 级堆内存。
执行阶段
  1. 初始标记(STW):标记根对象,耗时极短。
  2. 并发标记:与应用线程并行标记可达对象。
  3. 再标记(STW):处理并发标记期间的引用变动,耗时极短。
  4. 并发转移:移动存活对象到新 Region,通过读屏障修正所有引用。
关键参数
-XX:+UseZGC              # 启用 ZGC(JDK 11+)
-XX:ZHeapMaxSize=8t      # 最大堆内存(支持 TB 级)
-XX:ZCollectionInterval=1000 # 强制 GC 间隔(毫秒,避免碎片累积)
适用场景
  • 超大堆内存(16GB-8TB)且 对延迟敏感 的场景(如金融交易、实时数据处理)。
  • 云原生环境(如 Kubernetes 弹性扩缩容),需快速启动和低停顿。
优缺点
优点缺点
停顿时间 <10ms,几乎无感知吞吐量略低于 G1(约 95%)
支持动态堆大小调整仅 JDK 11+ 可用,需谨慎适配
分代设计(JDK 15+)提升年轻代回收效率

六、Shenandoah(OpenJDK 低延迟回收器)

核心机制
  • 转发指针(Forwarding Pointer)
    • 在对象头中添加指针,指向对象的新地址(移动后通过该指针修正引用)。
  • 布鲁姆过滤器(Bloom Filter)
    • 快速判断对象是否已被移动,减少无效的指针扫描,提升并发性能。
  • 并发标记 - 复制
    • 与 ZGC 类似,全程并发执行,仅初始标记和最终标记有短暂 STW。
执行阶段
  1. 初始标记(STW):标记根对象。
  2. 并发标记:与应用线程并行标记可达对象。
  3. 最终标记(STW):处理漏标的对象,耗时短。
  4. 并发回收:移动存活对象到新 Region,通过转发指针更新引用。
关键参数
-XX:+UseShenandoahGC     # 启用 Shenandoah(OpenJDK 12+)
-XX:ShenandoahGCMode=主动/被动 # 触发模式(主动模式基于内存阈值,被动响应分配压力)
-XX:MaxGCPauseMillis=10  # 目标停顿时间(默认 10ms)
适用场景
  • 大内存(8GB-2TB)且 需要 OpenJDK 原生支持 的场景(如开源项目、非商业环境)。
  • 对吞吐量要求中等,但需严格控制延迟的应用(如消息中间件、实时分析系统)。
优缺点
优点缺点
停顿时间与 ZGC 相当吞吐量低于 G1(约 90%)
内存占用低(转发指针仅占对象头)商业 JDK 需授权(OpenJDK 免费)
社区活跃,适配性强调优参数较多,需深入理解机制

七、横向对比表格

维度Serial GCParallel GCCMSG1ZGCShenandoah
设计目标简单单线程高吞吐量低延迟(老年代)平衡吞吐量与延迟超低延迟(TB 级)超低延迟(OpenJDK)
堆大小推荐小(<1GB)中等(4-8GB)中大(8-16GB)大(8GB+)超大(16GB+)大(8GB-2TB)
STW 时间中等短(老年代并发)可控(<500ms)极短(<10ms)极短(<10ms)
算法核心复制 + 标记整理并行复制 + 整理并发标记 - 清除分区 + 混合回收着色指针 + 并发整理转发指针 + 并发复制
适用场景嵌入式 / 单核心后台计算Web 服务微服务 / 中间件金融 / 实时数据开源 / OpenJDK 环境
JDK 版本全版本全版本JDK 1.4+JDK 7+JDK 11+OpenJDK 12+
典型参数-XX:+UseSerialGC-XX:+UseParallelGC-XX:+UseConcMarkSweepGC-XX:+UseG1GC-XX:+UseZGC-XX:+UseShenandoahGC

八、选择建议

  1. 小内存 / 简单场景
    • 优先选 Serial GC(单核心)或 Parallel GC(多核、需吞吐量)。
  2. 中等内存 / 低延迟需求
    • 选 CMS(老年代对象多)或 G1(对象分配频繁、需分代回收)。
  3. 大内存 / 超低延迟
    • 商业场景选 ZGC(JDK 11+,Oracle/OpenJDK);
    • 开源场景选 Shenandoah(OpenJDK 12+,避免授权问题)。
  4. 云原生 / 弹性扩缩容
    • 优先 ZGC(支持动态堆调整和超大内存)。

九、发展趋势

  • ZGC/Shenandoah 主导未来:逐步替代 G1 成为大内存场景的默认选择。
  • 分代与并发结合:如 ZGC 支持分代(JDK 15+),提升年轻代回收效率。
  • 硬件协同优化:利用 CPU 特性(如 AMD 的 MMU 分页)加速 GC 指针操作。

通过理解不同垃圾回收器的设计 trade-off,可根据具体业务需求(吞吐量、延迟、内存大小)选择最优方案,或通过组合参数(如 G1 的 -XX:InitiatingHeapOccupancyPercent)进一步调优。

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

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

相关文章

从零开始学习three.js(21):一文详解three.js中的矩阵Matrix和向量Vector

一、三维世界的数学基石 在Three.js的三维世界里&#xff0c;所有视觉效果的实现都建立在严密的数学基础之上。其中向量&#xff08;Vector&#xff09; 和矩阵&#xff08;Matrix&#xff09; 是最核心的数学工具&#xff0c;它们就像构建数字宇宙的原子与分子&#xff0c;支…

ArcGIS Pro 3.4 二次开发 - 内容

环境&#xff1a;ArcGIS Pro SDK 3.4 .NET 8 文章目录 内容1 工程1.1 创建一个空工程1.2 使用指定名称创建新工程1.3 使用Pro的默认设置创建新工程1.4 使用自定义模板文件创建新工程1.5 使用 ArcGIS Pro 提供的模板创建工程1.6 打开现有工程1.7 获取当前工程1.8 获取当前工程的…

【Python-Day 15】深入探索 Python 字典 (下):常用方法、遍历、推导式与嵌套实战

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

31、魔法生物图鉴——React 19 Web Workers

一、守护神协议&#xff08;核心原理&#xff09; 1. 灵魂分裂术&#xff08;线程架构&#xff09; // 主组件中初始化Workerconst workerRef useRef(null);​useEffect(() > {workerRef.current new Worker(new URL(./creatureWorker.js, import.meta.url));workerRef.…

Spark SQL 之 Antlr grammar 具体分析

src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseLexer.g4 BACKQUOTED_IDENTIFIER: ` ( ~` | `` )* `;src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBaseParser.g4 queryPrimary:

低功耗:XILINX FPGA如何优化功耗?

优化Xilinx FPGA及其外围电路的功耗需要从硬件设计、软件配置和系统级优化三个层面综合考虑。以下是具体的优化策略&#xff0c;涵盖硬件和软件方面&#xff1a; 一、硬件层面的功耗优化 选择低功耗FPGA型号 选择Xilinx低功耗系列芯片&#xff0c;如7系列中的Artix-7&#xff…

深入理解 ZAB:ZooKeeper 原子广播协议的工作原理

目录 ZAB 协议&#xff1a;ZooKeeper 如何做到高可用和强一致&#xff1f;&#x1f512;ZAB 协议的核心目标 &#x1f3af;ZAB 协议的关键概念 &#x1f4a1;ZAB 协议的运行阶段 &#x1f3ac;阶段一&#xff1a;Leader 选举 (Leader Election) &#x1f5f3;️阶段二&#xff…

OpenHarmony外设驱动使用 (五),Fingerprint_auth

OpenHarmony外设驱动使用 &#xff08;五&#xff09; Fingerprint_auth 概述 功能简介 指纹认证是端侧设备不可或缺的功能&#xff0c;为设备提供用户认证能力&#xff0c;可应用于设备解锁、支付、应用登录等身份认证场景。用户注册指纹后&#xff0c;指纹认证模块就可为设…

前端(vue)学习笔记(CLASS 6):路由进阶

1、路由的封装抽离 将之前写在main.js文件中的路由配置与规则抽离出来&#xff0c;放置在router/index.js文件中&#xff0c;再将其导入回main.js文件中&#xff0c;即可实现路由的封装抽离 例如 //index.js import { createMemoryHistory, createRouter } from vue-routerim…

前后端交互中的绝对路径和相对路径

前端 <form action"hello" method"post"> 1. 不加斜杠 &#xff08;相对路径&#xff0c;如 action"hello"&#xff09; 解析规则&#xff1a;基于当前页面的 URL 路径部分 进行拼接。 假设当前页面 URL 是 http://域名:端口/应用上下文…

在Odoo 18中创建进度条指南

在Odoo 18中创建进度条指南 一、创建进度条模板 首先在名为 progress_bar_widget.xml 的文件中定义一个名为 ProgressBarWidget 的新模板。该模板使用两个CSS类&#xff1a;progress-bar-inner 用于样式化进度条&#xff0c;progress_number 用于显示进度百分比。您可以根据需…

Linux grep 命令详解:常用选项、参数及实战场景

一、grep 命令简介 grep&#xff08;Global Regular Expression Print&#xff09;是 Linux 中用于文本搜索的核心工具&#xff0c;支持正则表达式&#xff0c;能快速定位文件中的目标内容。 二、常用选项&#xff08;Options&#xff09;及英文对照 | 选项 | 英文全称 | 作用 …

【Java-EE进阶】SpringBoot针对某个IP限流问题

目录 简介 1. 使用Guava的RateLimiter实现限流 添加Guava依赖 实现RateLimiter限流逻辑 限流管理类 控制器中应用限流逻辑 2. 使用计数器实现限流 限流管理类 控制器中应用限流逻辑 简介 针对某个IP进行限流以防止恶意点击是一种常见的反爬虫和防止DoS的措施。限流策…

Linux问题排查-找到偷偷写文件的进程

在 Linux 系统中&#xff0c;若要通过已修改的文件找到修改该文件的进程 PID&#xff0c;可以结合以下方法分析&#xff0c;具体取决于文件是否仍被进程打开或已被删除但句柄仍存在&#xff1a; 一、文件仍被进程打开&#xff08;未删除&#xff09; 如果文件当前正在被某个进…

More Effective C++:改善编程与设计(下)

目录 条款19:了解临时对象的来源 条款20:协助完成“返回值优化” 条款21:利用重载技术避免隐式类型转换 条款22:考虑以操作符复合形式&#xff08;op&#xff09;取代其独身形式&#xff08;op&#xff09; 条款23:考虑使用其他程序库 条款24:了解virtual functions、mul…

VTK|类似CloudCompare的比例尺实现2-vtk实现

文章目录 实现类头文件实现类源文件调用逻辑关键问题缩放限制问题投影模式项目git链接实现类头文件 以下是对你提供的 ScaleBarController.h 头文件添加详细注释后的版本,帮助你更清晰地理解每个成员和方法的用途,尤其是在 VTK 中的作用: #ifndef SCALEBARCONTROLLER_H #de…

PostgreSQL 联合索引生效条件

最近面试的时候&#xff0c;总会遇到一个问题 在 PostgreSQL 中&#xff0c;联合索引在什么条件下会生效&#xff1f; 特此记录~ 前置信息 数据库版本 PostgreSQL 14.13, compiled by Visual C build 1941, 64-bit 建表语句 CREATE TABLE people (id SERIAL PRIMARY KEY,c…

SpringBoot项目里面发起http请求的几种方法

在Spring Boot项目中发起HTTP请求的方法 在Spring Boot项目中&#xff0c;有几种常用的方式可以发起HTTP请求&#xff0c;以下是主要的几种方法&#xff1a; 1. 使用RestTemplate (Spring 5之前的主流方式) // 需要先注入RestTemplate Autowired private RestTemplate restT…

《Python星球日记》 第90天:微调的概念以及如何微调大模型?

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、微调原理1. 什么是大模型微调?2. 为什么需要微调?3. 微调的基本流程4. 微调策略分类二、LoRA(Low-Rank Adaptation)技术详解1. LoRA的核…

机器学习-人与机器生数据的区分模型测试 - 模型融合与检验

模型融合 # 先用普通Pipeline训练 from sklearn.pipeline import Pipeline#from sklearn2pmml.pipeline import PMMLPipeline train_pipe Pipeline([(scaler, StandardScaler()),(ensemble, VotingClassifier(estimators[(rf, RandomForestClassifier(n_estimators200, max_de…