# 浅析Hotspot经典7种垃圾收集器原理特点与组合搭配

HotSpot共有7种垃圾收集器,3个新生代垃圾收集器,3个老年代垃圾收集器,以及G1,一共构成7种可供选择的垃圾收集组合
新生代与老年代垃圾收集之间形成6种组合,每个新生代垃圾收集器都对应2种组合。

新生代垃圾收集

所有新生代垃圾收集器,都使用复制算法,都会发生stoptheworld。由于绝大多数对象生命周期通常比较短,在新生代被回收可能性很大,新生代的垃圾回收通常可以回收部分对象,因此采用复制算法效率更高。

Serial

采用复制算法,GC时发生stoptheworld,使用单个GC线程
“Serial” is a stop-theworld, copying collector which uses a single GC thread.
特点:

⠀Serial/Serial Old收集器协同工作运行示意图如下

在这里插入图片描述

ParNew

采用复制算法,GC时发生stop-the-world,使用多个GC线程
ParNew 与 Parallel Scavenge的一个主要区别是,ParNew可以与CMS进行搭配使用。
“ParNew” is a stopthe-world, copying collector which uses multiple GC threads. It differs from “Parallel Scavenge” in that it has enhancements that make it usable with CMS. For example, “ParNew” does the synchronization needed so that it can run during the concurrent phases of CMS.
特点:

Parallel Scavenge

采用复制算法,GC时发生stopthe-world,使用多个GC线程吞吐量优先收集器,可控制最大垃圾收集停顿时间(-XX:MaxGCPauseMillis)与吞吐量大小(-XX:GCTimeRatio),支持GC自适应调节策略(GC Ergonomics对应参数-XX:+UseAdaptiveSizePolicy)。
“Parallel Scavenge” is a stopthe-world, copying collector which uses multiple GC threads.
特点:

ParNew和Parallel Scavenge基本什么区别,都是年轻代的垃圾回收器,就是在Parallel Scavenge的基础上做了一些简单的增强使其能够较好的配合CMS的使用,ParNew是Parallel Scavenge的一个变种
ParNew响应时间优先,Parallel Scavenge吞吐量优先

吞吐量
吞吐量就是CPU用于运行用户代码时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间
假设虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。
通常来说,停顿时间越短(低延迟)就越适合需要用户交互需要保证服务响应质量程序, 良好的响应速度提升用户体验
而高吞吐量则可以最高效率利用处理器资源,尽快完成程序运算任务, 主要适合在后台运算而不需要太多交互分析任务

年代垃圾收集器

除了CMS,其他的老年代垃圾收集器GC时都是stopthe-world,都会在清理垃圾之后进行压缩整理

Serial Old

采用标记整理算法,GC时发生stopthe-world,使用单个GC线程
“Serial Old” is a stop-the-world, marksweepcompact collector that uses a single GC thread.
特点:

⠀Serial/Serial Old收集器协同工作运行示意图如下
在这里插入图片描述

Parallel Old

采用标记整理算法,GC时发生stop-the-world,使用多个GC线程
“Parallel Old” is a compacting collector that uses multiple GC threads.
特点:

整合压缩算法
对内存进行整合压缩是指在垃圾回收过程中对内存中的对象进行整理和重新排列通过存活对象向一端移动,以创建更大的连续内存空间,减少内存碎片提高内存利用率的过程。这通常涉及将对象复制到新的内存空间然后将原来的内存空间释放。这个过程通常发生在老年代的垃圾回收中。

⠀Parallel Scavenge/Parallel Old 收集器运行示意图如下
在这里插入图片描述

CMS

CMS采用标记清理算法,是一个以低暂停时间为目标的垃圾收集器。GC时大部分时间并发执行,其中初始化标记和重新标记两个阶段仍然会发生stop-the-world,其余阶段都是并发执行
“CMS” is a mostly concurrent, lowpause collector.
Java之CMS GC的7个阶段https://mp.weixin.qq.com/s/vmnBlrM7pTtVuyQU-GTcPw

收集流程
CMS整个过程的四个步骤如下,其中初始标记、 重新标记这两个步骤仍然需要“Stop The World”。
1. 初始标记-仅仅只是标记一下GC Roots直接关联到的对象速度很快
2. 并发标记-从GC Roots直接关联对象开始遍历整个对象图的过程这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行
3. 重新标记-为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录这个阶段的停顿时间通常会比初始标记阶段稍长一些, 但也远比并发标记阶段的时间短
4. 并发清除清理删除掉标记阶段判断的已经死亡的对象, 由于不需要移动存活对象, 所以这个阶段也是可以用户线程同时并发的
Concurrent Mark Sweep 收集器运行示意图如下
在这里插入图片描述

缺点:

关于CMS收集器浮动垃圾的说明
由于在CMS的并发标记和并发清理阶段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们, 只好留待下一次垃圾收集时再清理掉。这一部分垃圾就称为浮动垃圾”。
由于在垃圾收集阶段用户线程还需要持续运行, 那就还需要预留足够内存空间提供给用户线程使用, 因此CMS收集器不能像其他收集器那样等待到老年代几乎完全被填满了再进行收集,必须预留一部分空间供并发收集时的程序运作使用

G1

G1将整个堆划分为多个大小相等独立区域(Region),保留新生代和老年代的分代概念(但两者不再是物理隔离的)。
整体来看是基于标记整理算法,从局部两个Region之间)来看是基于复制算法。因此,可以避免产生内存空间碎片,防止发生并发模式失败
使用多个GC线程,每次优回收价值最大的Region
支持预测的停顿时间模型,从而提高收集效率,降低stop-the-world的时间
The Garbage First or G1 garbage collector is available in Java 7 and is designed to be the long term replacement for the CMS collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector that has quite a different layout from the other garbage collectors described previously.

特点:

G1 收集器 Region 分区示意图如下
在这里插入图片描述

G1 收集器的运作过程主要步骤如下

⠀从上述阶段的描述可以看出, G1收集器除了并发标记外, 其余阶段也是要完全暂停用户线程的,换言之, 它并非纯粹地追求低延迟, 官方给它设定的目标是在延迟可控的情况下获得尽可能高的吞吐量。

G1 收集器运行示意图如下:
在这里插入图片描述

G1 收集器与 CMS 收集器的异同

垃圾回收器器组合搭配

Serial Old(MSC)可以与所有新生代收集器进行组合,共3种组合

JVM仅指定新生代垃圾收集器的情况下,默认老年代采用Serial Old垃圾收集器(带压缩

-XX:+UseSerialGC

Serial (DefNew) + Serial Old(Serial Mark Sweep Compact)

-XX:+UseParNewGC

Parallel (ParNew) + Serial Old(Serial Mark Sweep Compact)

-XX:+UseParallelGC

Parallel Scavenge (PSYoungGen) + Serial Old(Serial Mark Sweep Compact (PSOldGen))
注:在Parallel Scavenge收集器架构中本身有PS MarkSweep收集器来进行老年代收集,但由于PS MarkSweep与Serial Old实现非常接近,因此官方的许多资料直接以Serial Old代替PS MarkSweep进行讲解

Parallel Old(带压缩)只能与Parallel Scavenge进行组合

-XX:+UseParallelOldGC

Parallel Scavenge (PSYoungGen) + Parallel Mark Sweep Compact (ParOldGen)

CMS(不带压缩)可以与Serial和ParNew进行组合,共2种组合

-XX:-UseParNewGC -XX:+UseConcMarkSweepGC

Serial (DefNew) + CMS(Concurrent Mark Sweep)

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

Parallel (ParNew) + CMS(Concurrent Mark Sweep) + Serial Old(Serial Mark Sweep Compact

G1(Garbage First),不需要搭配其他垃圾收集器

-XX:+UseG1GC

6种垃圾收集组合关系

在这里插入图片描述

在这里插入图片描述

推荐使用的2种GC组合

1.基于低停顿时间的垃圾收集器

-XX:+UseConcMarkSweepGC(该参数隐式启用-XX:+UseParNewGC)

2.基于吞吐量优先的垃圾收集器

-XX:+UseParallelOldGC(该参数隐式启用-XX:+UseParallelGC)

在这里插入图片描述

总结

下面对这七种垃圾收集器进行了一个总结,具体如下表所示

收集器 串行并行、并发 新生代/老年代 算法 目标 使用场景
Serial 串行 新生代 复制算法 响应速度优先 单CPU环境下的Client模式
ParNew 并行 新生代 复制算法 响应速度优先 多CPU环境时再Server模式下与CMS配合
Parallel Scavenge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
Serial Old 串行 老年代 标记-整理 响应速度优先 单CPU环境下的Client模式 CMS的后备预案
Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 标记-清除 响应速度优先 集中互联网站或B/S系统服务端
G1 并发 新生代/老年代 标记-整理/复制算法 响应速度优先 面向服务端应用用来替换CMS

参考
HotSpot的7种垃圾收集器组合
浅析经典JVM垃圾收集器-Serial/ParNew/Parallel Scavenge/Serial Old/Parallel Old/CMS/G1
https://blogs.oracle.com/
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
https://www.splunk.com/en_us/products/apm-application-performance-monitoring.html?source=plumbr
《深入理解Java虚拟机 JVM高级特性与最佳实践》周志明
《Java性能权威指南
Java之CMS GC的7个阶段:https://mp.weixin.qq.com/s/vmnBlrM7pTtVuyQU-GTcPw

原文地址:https://blog.csdn.net/Urbanears/article/details/134793822

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_40432.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注