news 2026/6/10 10:53:48

JVM实战:垃圾收集器及其适用场景

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JVM实战:垃圾收集器及其适用场景

垃圾收集器


图中展示了七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。在JDK8时将Serial+CMS,ParNew+Serial Old这两个组合声明为废弃,并在JDK9中完全取消了这些组合的支持


并行和并发都是并发编程中的专业名词,在谈论垃圾收集器的上下文语境中, 它们可以理解为

并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态

并发(Concurrent):指用户线程与垃圾收集线程同时执行

串行收集器

Serial收集器

新生代,标记-复制算法,单线程。进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束

Serial Old收集器

老年代,标记-整理算法,单线程,是Serial收集器的老年代版本

用处有如下2个

  1. 在JDK5以及之前的版本中与Parallel Scavenge收集器搭配使用
  2. 作为CMS收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用

并行收集器

Parallel Scavenge收集器

新生代,标记复制算法,多线程,主要关注吞吐量

吞吐量=运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)

Parallel Old收集器

老年代,标记-整理算法,多线程,是Parallel Scavenge收集器的老年代版本

在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器这个组合

ParNew收集器

ParNew本质上是Serial收集器的多线程并行版本

CMS收集器

老年代,标记-清除算法,多线程,主要关注延迟

运作过程分为4个步骤

  1. 初始标记(CMS initial mark)
  2. 并发标记(CMS concurrent mark)
  3. 重新标记(CMS remark)
  4. 并发清除(CMS concurrent sweep)

  1. 初始标记:标记一下GC Roots能直接关联到的对象,速度很快(这一步会发生STW)
  2. 并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集一起并发运行
  3. 重新标记:为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(就是三色标记法中的增量更新,这一步也会发生STW)
  4. 并发清除:清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以看这个阶段也是可以与用户线程同时并发的

因为目前ParNew+CMS的组合最常用,因此我们就接着来看看CMS有哪些问题?

1.并发回收垃圾导致CPU资源紧张

并发标记和并发清理阶段,垃圾回收线程和系统工作线程同时工作,会导致有限的CPU资源被垃圾回收线程占用了一部分

2.无法处理浮动垃圾

在并发清理阶段,CMS回收的是之前标记好的对象,但是这个阶段系统一直在运行,有可能会产生新的垃圾对象,这种垃圾对象就是“浮动垃圾”,浮动垃圾只能等到下一次GC才会被回收

3.Concurrent Mode Failure导致垃圾收集器切换到SerialOld

如果在CMS垃圾回收期间,程序要放入老年代的对象大于了可用内存空间,会发生Concurrent Mode Failure,就是说并发垃圾回收失败,我一边回收,你一边把对象放入老年代,内存都不够用了。此时就会用SerialOld替换CMS,直接 Stop the World 进行垃圾回收,一次性把垃圾对象都回收掉

4.CMS用的是标记清除算法,会导致大量的内存碎片

G1收集器

G1收集器最大的特点就是把堆划分成多个大小相等的Region

G1也会有新生代和老年代的概念,但是是逻辑上的概念,并不是物理上的概念。一个Region有可能属于新生代有可能属于老年代,新生代和老年代的内存区域是不停变动的,由G1自动控制

在G1之前的垃圾收集器,当发生GC的时候,要么回收整个新生代,要么回收整个老年代。而G1可以面向堆内存的任何部分进行回收,Region是单次回收的基本单元

有了Region作为单次回收的基本单元,就能建立可预测停顿时间模型,即我们可以通过设置 -XX:MaxGCPauseMillis 参数来控制STW的时间,G1尽可能的在这个时间内完成垃圾收集,并且G1会优先回收价值收益大的Region(即花的时间少并且回收的垃圾还多)

G1收集器的运行过程如下

  1. 初始标记:标记一下GC Roots能直接关联到的对象,速度很快(这一步会发生STW)
  2. 并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集一起并发运行
  3. 最终标记:为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(就是三色标记法中的原始快照,这一步也会发生STW)
  4. 筛选回收:根据用户期望的停顿时间,回收部分Region。首先把要回收的Region中的存活对象复制到空的Region,在清理掉旧Region的空间

与CMS的“标记-清除”算法不同, G1从整体来看是基于“标记-整理”算法实现的收集器, 但从局部(两个Region之间) 上看又是基于“标记-复制”算法实现, 无论如何, 这两种算法都意味着G1运作期间不会产生内存空间碎片, 垃圾收集完成之后能提供规整的可用内存。 这种特性有利于程序长时间运行, 在程序为大对象分配内存时不容易因无法找到连续内存空间而提前触发下一次收集

总结

|收集器 | 收集对象和算法 |收集器类型| 说明 | 适用场景 |
|–|–|–|–|–|–|
| Serial| 新生代,复制算法 |单线程| | 简单高效;适合内存不大的情况|
| ParNew| 新生代,复制算法|并行的多线程收集器| ParNew垃圾收集器是Serial收集器的多线程版本 | 搭配CMS垃圾回收器的首选 |
| Parallel Scavenge吞吐量优先收集器|新生代,复制算法 | 并行的多线程收集器 |类似ParNew,更加关注吞吐量,达到一个可控制的吞吐量|本身是Server级别多CPU机器上的默认GC方式,主要适合后台运算不需要太多交互的任务|

|收集器 | 收集对象和算法 |收集器类型| 说明 | 适用场景 |
|–|–|–|–|–|–|
| Serial Old| 老年代,标记整理算法|单线程| | Client模式下虚拟机使用|
| Parallel Old| 老年代,标记整理算法|并行的多线程收集器|Paraller Scavenge收集器的老年代版本,为了配置Parallel Svavenge的面向吞吐量的特性而开发的对应组合 |在注重吞吐量以及CPU资源敏感的场合采用 |
|CMS |老年代,标记清除算法| 并行与并发收集器|尽可能的缩短垃圾收集时用户线程停止时间;缺点在于,1.内存碎片,2.需要更多CPU资源,3.浮动垃圾问题,需要更大的堆空间| 重视服务的相应速度,系统停顿时间和用户体验的互联网网站或者B/S系统。互联网后端目前cms是主流的垃圾回收器|
|G1|跨新生代和老年代;标记整理 |并行与并发收集器|| JDK1.7才正式引入,采用分区回收的思维,基本不牺牲吞吐量的前提下完成低停顿的内存回收;可预测的停顿是其最大的优势|面向服务端应用的垃圾回收器,目标为取代CMS|

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

AssertK协程测试指南:Flow与挂起函数的断言技巧

AssertK协程测试指南:Flow与挂起函数的断言技巧 【免费下载链接】assertk assertions for kotlin inspired by assertj 项目地址: https://gitcode.com/gh_mirrors/as/assertk AssertK是一款受AssertJ启发的Kotlin断言库,专为Kotlin开发者设计简洁…

作者头像 李华
网站建设 2026/6/10 10:42:07

3分钟识破假U盘:F3闪存检测工具完全指南

3分钟识破假U盘:F3闪存检测工具完全指南 【免费下载链接】f3 F3 - Fight Flash Fraud 项目地址: https://gitcode.com/gh_mirrors/f3/f3 在数字时代,闪存设备已成为我们日常数据存储的重要工具。然而,市场上充斥着大量容量虚标的"…

作者头像 李华
网站建设 2026/6/10 10:41:12

蓝鲸CMDB配置管理平台:企业IT资源管理的终极解决方案

蓝鲸CMDB配置管理平台:企业IT资源管理的终极解决方案 【免费下载链接】bk-cmdb 蓝鲸智云配置平台(BlueKing CMDB) 项目地址: https://gitcode.com/gh_mirrors/bk/bk-cmdb 蓝鲸智云配置平台(BlueKing CMDB)是腾讯开源的企业级配置管理数…

作者头像 李华
网站建设 2026/6/10 10:37:22

深度学习模型转换终极指南:从TensorFlow到CoreML的完整流程

深度学习模型转换终极指南:从TensorFlow到CoreML的完整流程 【免费下载链接】awesome-machine-learning 🎰 A curated list of machine learning resources, preferably CoreML 项目地址: https://gitcode.com/gh_mirrors/awe/awesome-machine-learnin…

作者头像 李华
网站建设 2026/6/10 10:33:09

Lune:革命性Luau运行时——下一代脚本语言的完整解决方案

Lune:革命性Luau运行时——下一代脚本语言的完整解决方案 【免费下载链接】lune A standalone Luau runtime 项目地址: https://gitcode.com/gh_mirrors/lu/lune Lune是一款功能强大的独立Luau运行时,为开发者提供了完整的脚本语言解决方案。它不…

作者头像 李华