news 2026/3/8 13:59:33

Java垃圾收集器全解:从Serial到G1的进化之旅

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java垃圾收集器全解:从Serial到G1的进化之旅

概述

在Java的世界里,垃圾收集器就像是默默无闻的清洁工,在我们不注意的时候悄悄清理内存垃圾。不同的清洁工有不同的工作方式,有的喜欢一次性彻底打扫(Stop The World),有的则喜欢边工作边让你继续玩耍(并发收集)。今天,就让我们一起来认识这些各具特色的"清洁工"吧!

收集器家族一览

新生代收集器

1. Serial收集器 - "单干的老黄牛"

工作方式:单线程,Stop The World算法:标记-复制适用场景:客户端模式,内存受限环境

Serial收集器就像是一位勤劳的清洁阿姨,每次打扫时都需要你暂时离开房间(Stop The World)。她工作认真,但没有帮手,只能一件一件地清理。

详细介绍:Serial收集器是Java最古老的新生代收集器,采用单线程执行垃圾回收工作。当它工作时,会暂停所有应用线程(Stop The World),直到收集完成。这种"全世界暂停"的方式虽然简单粗暴,但在特定场景下却非常有效。

核心特点

  • 单线程工作,收集时暂停所有应用线程

  • 采用标记-复制算法,将Eden区和From Survivor区的存活对象复制到To Survivor区

  • 额外内存消耗最小,只需要维护一个线程的开销

  • 在单核处理器环境下效率很高,没有线程交互开销

配置参数

  • -XX:+UseSerialGC:启用Serial收集器

  • -XX:SurvivorRatio:Eden与Survivor区的比例

  • -XX:PretenureSizeThreshold:大对象直接进入老年代的阈值

适用场景

  • 客户端应用,如桌面程序、小程序

  • 小内存环境(几十到几百MB的新生代)

  • 单核或双核处理器环境

  • 对停顿时间不敏感的应用

优缺点

  • ✅ 优点:实现简单、内存开销小、单核环境下效率高

  • ❌ 缺点:停顿时间长、在多核环境下无法充分利用CPU资源

2. ParNew收集器 - "多人协作的清洁队"

工作方式:多线程,Stop The World算法:标记-复制适用场景:与CMS配合的服务端应用

ParNew就像是Serial的升级版,从单人作战变成了团队协作。但它仍然需要在工作时让所有人暂时离开房间。

详细介绍:ParNew收集器是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集外,其他行为与Serial收集器完全一致。它与Serial收集器共用了大量的代码,可以看作是Serial的并行化改造。

核心特点

  • 多线程并行收集,默认线程数与CPU核心数相同

  • 采用与Serial相同的标记-复制算法

  • 需要Stop The World,但停顿时间比Serial短

  • 与CMS收集器配合工作

配置参数

  • -XX:+UseParNewGC:启用ParNew收集器

  • -XX:ParallelGCThreads:设置垃圾收集线程数

  • -XX:SurvivorRatio:Eden与Survivor区的比例

适用场景

  • 与CMS收集器配合使用

  • 多核处理器的服务端应用

  • 对响应时间有一定要求的应用

工作流程

  1. 暂停所有应用线程(Stop The World)

  2. 多线程并行标记存活对象

  3. 多线程并行复制存活对象到Survivor区

  4. 清理Eden区和From Survivor区

  5. 恢复应用线程

优缺点

  • ✅ 优点:多线程并行收集,停顿时间比Serial短

  • ❌ 缺点:仍然需要Stop The World,单核环境下性能不如Serial

3. Parallel Scavenge收集器 - "效率至上的工厂流水线"

工作方式:多线程,Stop The World算法:标记-复制适用场景:后台运算,吞吐量优先应用

Parallel Scavenge不像是在打扫房间,更像是在优化工厂生产线。它不关心每次停顿多久,只关心单位时间内能完成多少工作。

详细介绍:Parallel Scavenge收集器是一款专注于吞吐量的新生代收集器。它的目标是达到一个可控制的吞吐量(Throughput),即处理器用于运行用户代码的时间与处理器总消耗时间的比值。

核心特点

  • 关注点是吞吐量而非停顿时间

  • 提供精确控制吞吐量的参数

  • 支持自适应调节策略

  • 采用多线程并行收集

配置参数

  • -XX:+UseParallelGC:启用Parallel Scavenge收集器

  • -XX:MaxGCPauseMillis:最大垃圾收集停顿时间

  • -XX:GCTimeRatio:垃圾收集时间与总时间的比率

  • -XX:+UseAdaptiveSizePolicy:启用自适应策略

自适应策略:当启用自适应策略后,虚拟机会根据系统运行情况自动调整以下参数:

  • 新生代大小(-Xmn)

  • Eden与Survivor区的比例(-XX:SurvivorRatio)

  • 晋升老年代对象大小(-XX:PretenureSizeThreshold)

适用场景

  • 后台运算任务,如批量处理、数据分析

  • 对吞吐量要求高于响应时间的应用

  • 不需要与用户交互的应用

优缺点

  • ✅ 优点:吞吐量高、支持自适应调节、适合后台运算

  • ❌ 缺点:停顿时间不可控、不适合交互式应用

老年代收集器

4. Serial Old收集器 - "老黄牛的晚年生活"

工作方式:单线程,Stop The World算法:标记-整理适用场景:客户端模式,CMS失败时的备胎

Serial Old就像是Serial收集器退休后再就业,虽然年纪大了,但依然兢兢业业。

详细介绍:Serial Old是Serial收集器的老年代版本,同样采用单线程工作和Stop The World的方式。它使用标记-整理算法,避免内存碎片的产生。

核心特点

  • 单线程工作,需要Stop The World

  • 采用标记-整理算法

  • 内存开销小

  • 作为CMS失败时的备胎

工作流程

  1. 标记阶段:标记所有存活对象

  2. 整理阶段:将所有存活对象向一端移动

  3. 清理阶段:清理边界以外的内存

适用场景

  • 客户端模式下的老年代收集

  • 与Parallel Scavenge搭配使用(JDK5及之前)

  • CMS收集器发生Concurrent Mode Failure时的后备预案

配置参数

  • -XX:+UseSerialGC:启用Serial Old收集器

  • 通常与其他收集器配合使用,不需要单独配置

优缺点

  • ✅ 优点:实现简单、内存开销小、不会产生内存碎片

  • ❌ 缺点:停顿时间长、单线程效率低

5. Parallel Old收集器 - "流水线的完美搭档"

工作方式:多线程,Stop The World算法:标记-整理适用场景:与Parallel Scavenge搭配的吞吐量优先应用

Parallel Old的出现让Parallel Scavenge终于有了门当户对的搭档,形成了真正的"吞吐量优先"组合。

详细介绍:Parallel Old是Parallel Scavenge收集器的老年代版本,支持多线程并发收集,基于标记-整理算法实现。它在JDK6中才开始提供,填补了Parallel Scavenge没有匹配老年代收集器的空白。

核心特点

  • 多线程并行收集

  • 采用标记-整理算法

  • 专注于吞吐量优化

  • 与Parallel Scavenge完美配合

工作流程

  1. 标记阶段:多线程并行标记存活对象

  2. 整理阶段:多线程并行整理内存

  3. 清理阶段:清理不可达对象

适用场景

  • 与Parallel Scavenge搭配使用

  • 注重吞吐量的应用

  • 后台运算任务

配置参数

  • -XX:+UseParallelOldGC:启用Parallel Old收集器

  • 通常与Parallel Scavenge一起使用

优缺点

  • ✅ 优点:吞吐量高、多线程并行、与Parallel Scavenge配合良好

  • ❌ 缺点:停顿时间较长、不适合交互式应用

6. CMS收集器 - "边开派对边打扫的管家"

工作方式:并发,低停顿算法:标记-清除适用场景:B/S系统,重视响应速度的应用

CMS就像是一位技艺高超的管家,能够在派对进行中悄悄打扫,尽量不打扰宾客的雅兴。

详细介绍:CMS(Concurrent Mark Sweep)收集器是一款以获取最短回收停顿时间为目标的收集器,非常适合重视响应速度的应用。它采用标记-清除算法,尽可能减少Stop The World的时间。

工作流程

  1. 初始标记:标记GC Roots直接关联的对象(需要Stop The World,但很快)

  2. 并发标记:并发遍历对象图,标记所有可达对象

  3. 重新标记:修正并发标记期间变动的标记记录(需要Stop The World)

  4. 并发清除:并发清理垃圾对象

核心特点

  • 并发收集,低停顿时间

  • 采用标记-清除算法,会产生内存碎片

  • 对处理器资源敏感

  • 无法处理"浮动垃圾"

配置参数

  • -XX:+UseConcMarkSweepGC:启用CMS收集器

  • -XX:CMSInitiatingOccupancyFraction:老年代使用率触发阈值

  • -XX:+UseCMSCompactAtFullCollection:Full GC时开启内存压缩

  • -XX:CMSFullGCsBeforeCompaction:设置多少次Full GC后压缩一次

浮动垃圾问题:由于CMS的并发清理阶段用户线程仍在运行,会产生新的垃圾对象,这些对象无法在本次收集中处理,称为"浮动垃圾"。

适用场景

  • B/S系统服务端

  • 重视响应速度的应用

  • 互联网应用

优缺点

  • ✅ 优点:并发收集、低停顿时间、适合交互式应用

  • ❌ 缺点:对CPU资源敏感、会产生内存碎片、无法处理浮动垃圾

全堆收集器:G1 - "智能分区清洁系统"

工作方式:并发+并行算法:整体标记-整理,局部标记-复制适用场景:大内存服务端应用,兼顾吞吐量和停顿时间

G1收集器就像是现代智能清洁系统,将房间分成多个区域,每次只清理最脏的区域,并且能够预测清理需要的时间。

详细介绍:G1(Garbage First)收集器是垃圾收集器技术发展历史上的里程碑成果,开创了面向局部收集的设计思路和基于Region的内存布局形式。它旨在替代CMS收集器,提供更可控的停顿时间。

革命性创新

  1. 基于Region的堆内存布局:将堆划分为多个大小相等的Region

  2. 可预测的停顿时间模型:通过-XX:MaxGCPauseMillis参数设定期望停顿时间

  3. 面向局部收集:不再坚持固定分代,而是选择回收价值最大的Region

  4. Humongous区域:专门处理大对象

工作流程

  1. 初始标记:标记GC Roots直接关联的对象

  2. 并发标记:并发进行可达性分析

  3. 最终标记:处理并发标记期间的引用变动

  4. 筛选回收:根据回收价值排序,选择Region进行回收

配置参数

  • -XX:+UseG1GC:启用G1收集器

  • -XX:MaxGCPauseMillis:设置最大停顿时间目标

  • -XX:G1HeapRegionSize:设置Region大小

  • -XX:InitiatingHeapOccupancyPercent:触发并发标记周期的Java堆占用率阈值

适用场景

  • 大内存服务端应用(6GB以上)

  • 需要兼顾吞吐量和停顿时间的应用

  • 替代CMS收集器

优缺点

  • ✅ 优点:停顿时间可控、高吞吐量、不会产生内存碎片

  • ❌ 缺点:内存占用较高、写屏障实现复杂

如何选择收集器?

选择垃圾收集器就像选择清洁方式,需要根据实际情况决定:

小内存客户端应用(小于512MB)

  • Serial + Serial Old组合

  • 简单高效,内存开销小

重视响应速度的B/S系统

  • ParNew + CMS组合

  • 低停顿时间,适合交互式应用

后台运算,注重吞吐量

  • Parallel Scavenge + Parallel Old组合

  • 高吞吐量,适合批处理任务

大内存服务端应用(大于6GB)

  • G1收集器

  • 兼顾吞吐量和停顿时间

超大内存应用(大于32GB)

  • 考虑ZGC或Shenandoah

  • 极低停顿时间,适合超大内存

选择建议

  • 先明确应用需求:吞吐量优先还是响应时间优先

  • 根据堆内存大小选择

  • 在生产环境中进行实际测试验证

  • 随着JDK版本更新,优先考虑 newer 收集器

结语

Java垃圾收集器的发展历程就像清洁方式的进化:从最初需要全员离开的彻底打扫(Serial),到可以边工作边打扫的智能清洁(CMS),再到分区打扫、时间可控的现代清洁系统(G1)。每种收集器都有其适用场景,没有绝对的最好,只有最适合的。

随着JDK的持续发展,更新的收集器如ZGC、Shenandoah也在不断涌现,它们提供了更低的停顿时间和更好的性能表现。但理解这些基础收集器的工作原理,仍然是我们优化Java应用性能的基石。

希望本文能帮助你更好地理解Java垃圾收集器,选择适合的"清洁工",让你的Java应用跑得更加顺畅!记住,垃圾收集器的调优是一个持续的过程,需要根据实际应用特点和负载变化进行调整。

文章转载自:佛祖让我来巡山

原文链接:https://www.cnblogs.com/sun-10387834/p/19094842

体验地址:http://www.jnpfsoft.com/?from=001YH

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/7 14:29:12

14 类圣诞核心 SVG 交互方案拆解(附案例 + 资源)

1. 选择类交互:精准匹配礼物需求 交互方案核心逻辑品牌案例关键组件 / 操作要点学习资源挤压伸长以 “选择” 为核心,通过挤压交互引导用户筛选礼物类型OPARTMENT《圣诞爱意》、尚美《你的礼想型》「挤压伸长」(UGC 组件)&#x…

作者头像 李华
网站建设 2026/3/8 11:52:27

7个技巧轻松搞定Node.js版本升级:从16.x到20.x的无痛迁移指南

7个技巧轻松搞定Node.js版本升级:从16.x到20.x的无痛迁移指南 【免费下载链接】PowerShell PowerShell/PowerShell: PowerShell 是由微软开发的命令行外壳程序和脚本环境,支持任务自动化和配置管理。它包含了丰富的.NET框架功能,适用于Window…

作者头像 李华
网站建设 2026/3/6 9:38:19

MCP SC-400配置避坑手册(一线专家亲授10大常见错误)

第一章:MCP SC-400量子安全配置实务概述在当前量子计算快速发展的背景下,传统加密体系面临前所未有的破解风险。MCP SC-400作为新一代量子安全通信协议配置标准,专为抵御量子攻击设计,提供前向安全性、抗量子算法支持及动态密钥协…

作者头像 李华
网站建设 2026/3/5 20:35:33

Ghost没落、同行消失,深度却靠国产系统翻盘?关键点不止一个!

当年国内装机有多乱,可能好多人都想不起来了如果你经历过早年的网吧时代,你一定忘不了那个画面:电脑蓝屏,网管把U盘往机器上一插,Ghost一跑,十几分钟系统满血复活。那时候说是Ghost的黄金年代也不足为过。而…

作者头像 李华
网站建设 2026/3/8 1:10:12

5分钟掌握PROPKA:蛋白质pKa预测的终极入门指南

5分钟掌握PROPKA:蛋白质pKa预测的终极入门指南 【免费下载链接】propka PROPKA predicts the pKa values of ionizable groups in proteins and protein-ligand complexes based in the 3D structure. 项目地址: https://gitcode.com/gh_mirrors/pr/propka 想…

作者头像 李华
网站建设 2026/3/5 6:06:03

dotNetFx40_Full_x86_x64:解决Windows开发环境配置难题的终极方案

dotNetFx40_Full_x86_x64:解决Windows开发环境配置难题的终极方案 【免费下载链接】dotNetFx40_Full_x86_x64完整安装包 此项目提供 dotNetFx40_Full_x86_x64 完整安装包,适用于需要 Microsoft .NET Framework 4.0 的用户。该安装包包含 x86 和 x64 两个…

作者头像 李华