五分钟带你了解垃圾回收器

本文深入探讨了Java垃圾回收器的种类,包括串行、并行、并发和整堆收集器,如Serial、ParallelScavenge、CMS和G1。分析了各收集器的特点、工作模式和适用场景,强调了GC的性能指标,如吞吐量、暂停时间和内存占用。CMS和G1作为低延迟的代表,分别以并发标记清除和区域划分代式策略,提供更优的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

垃圾回收器

1.垃圾回收器概述

  • 如果说收集算法是内存回收的方法论,那么收集器就是内存回收的实践者.
  • 垃圾收集器没有在 java 虚拟机规范中进行过多的规定,可以由不同的厂商、 不同版本的 JVM 来实现。
  • 由于 JDK 的版本处于高速迭代过程中,因此 Java 发展至今已经衍生了众多 的 GC 版本。
  • 从不同角度分析垃圾收集器,可以将 GC 分为不同的类型。

2.垃圾回收器分类

按线程数分,可以分为串行垃圾回收器和并行垃圾回收器
在这里插入图片描述
串行回收指的是在同一时间段内只允许有一个 CPU 用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。
和串行回收相反,并行收集可以运用多个 CPU 同时执行垃圾回收,因此提 升了应用的吞吐量,不过并行回收仍然与串行回收一样,采用独占式,使用 "stop-the-world"机制。
按照工作模式分,可以分为并发式垃圾回收器和独占式垃圾回收器。
并发式垃圾回收器与应用程序线程交替工作,以尽可能减少应用程序的停顿 时间。独占式垃圾回收器(stop the world)一旦运行,就停止应用程序中的所有 用户线程,直到垃圾回收过程完全结束。
在这里插入图片描述
按工作的内存区间分,又可分为年轻代垃圾回收器和老年代垃圾回收器。

3. GC性能指标

  • 吞吐量:运行用户代码的时间占总运行时间的比例(总运行时间:程序的运 行时间+内存回收的时间)
  • 垃圾收集开销:垃圾收集所用时间与总运行时间的比例。
  • 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。
  • 收集频率:相对于应用程序的执行,收集操作发生的频率。
  • 内存占用:Java 堆区所占的内存大小。
  • 快速:一个对象从诞生到被回收所经历的时间。

4.HotSpot垃圾收集器

图中展示了 7 种作用于不同分代的收集器,如果两个收集器之间存在连线,则说明它们可以搭配使用。虚拟机所处的区域则表示它是属于新生代还是老年代收集器。
在这里插入图片描述

  • 串行回收器:Serial,Serial old
  • 并行回收器:ParNew,Parallel scavenge,Parallel old
  • 并发回收器:CMS、G1
    在这里插入图片描述
  • 新生代收集器:Serial,ParNew.Parallel scavenge;
  • 老年代收集器:Serial old.Parallel old.cMS;
  • 整堆收集器:G1;
    在这里插入图片描述
(1)Serial 垃圾收集器(单线程)

Serial收集器是最基本的、新生代的、发展历史最悠久的收集器。
特点: 单线程、简单高效,采用复制算法,对于限定单个 CPU 的环境来说,Serial 收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收 集效率。收集器进行垃圾回收时,必须暂停其他所有的工作线程,直到它结束 (Stop The World)。
应用场景: 适用于Client(客户) 模式下的虚拟机。
Serial / Serial Old 收集器运行示意图
在这里插入图片描述

(2)Serial Old 垃圾收集器(单线程)

Serial Old 是 Serial 收集器的老年代版本。
特点: 同样是单线程收集器,采用标记-整理算法。
应用场景: 主要也是使用在 Client 模式下的虚拟机中。也可在 Server 模式下使用。

(3)ParNew 垃圾收集器(多线程)

ParNew 收集器其实就是 Serial 收集器的多线程版本。
除了使用多线程外其余行为均和 Serial 收集器一模一样(参数控制、收集算法、Stop The World、对象分配规则、回收策略等)。
特点: 多线程、ParNew 收集器默认开启的收集线程数与 CPU 的数量相同,在 CPU 非常多的环境中,可以使用-XX:ParallelGCThreads 参数来限制垃圾收集 的线程数。和 Serial 收集器一样存在 Stop The World 问题。
应用场景: ParNew 收集器是许多运行在 Server 模式下的虚拟机中首选的新生 代收集器,因为它是除了 Serial 收集器外,唯一一个能与 CMS 收集器配合工作的。
ParNew/Serial Old 组合收集器运行示意图如下:
在这里插入图片描述

(4)Parallel Scavenge 垃圾收集器(多线程)

Parallel Scavenge 和 ParNew 一样,都是多线程、新生代垃圾收集器。 但是两者有巨大的不同点:
Parallel Scavenge:追求 CPU 吞吐量,能够在较短时间内完成指定任务, 因此适合没有交互的后台计算,。

(5)Parallel Old 垃圾收集器(多线程)

是 Parallel Scavenge 收集器的老年代版本。
特点: 多线程,采用标记-整理算法。
应用场景: 注重高吞吐量以及 CPU 资源敏感的场合,都可以优先考虑 Parallel Scavenge+Parallel Old 收集器。
在这里插入图片描述

(6)CMS 回收器(低延迟)

CMS(Concurrent Mark Sweep,并发标记清除)收集器是以获取最短回收停顿 时间为目标的收集器(追求低停顿),它在垃圾收集时使得用户线程和 GC 线程并 发执行,因此在垃圾收集过程中用户也不会感到明显的卡顿。

  • 初始标记:Stop The World,仅使用一条初始标记线程对所有与 GC Roots 直 接关联的对象进行标记。
  • 并发标记:使用多条标记线程,与用户线程并发执行。此过程进行可达性分析, 标记出所有废弃对象。速度很慢。
  • 重新标记:Stop The World,使用多条标记线程并发执行,将刚才并发标记过 程中新出现的废弃对象标记出来。
  • 并发清除:只使用一条 GC 线程,与用户线程并发执行,清除刚才标记的对象。 这个过程非常耗时。

并发标记与并发清除过程耗时最长,且可以与用户线程一起工作,因此,总体上 说,CMS 收集器的内存回收过程是与用户线程一起并发执行的。
在这里插入图片描述
CMS的优点:

  • 并发收集
  • 低延迟
    CMS的弊端:
  1. 会产生内存碎片, 导致并发清除后,用户线程可用的空间不足。在无法分配 大对象的青况下,不得不提前触发 Ful1 GC.
  2. CMS 收集器对 CPU 资源非常敏感。 在并发阶段,它虽然不会导致用户停顿, 但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
(7)G1(Garbage First)回收器(区域划分代式)

既然我们已经有了前面几个强大的 GC,为什么还要发布 Garbage First(G1) GC呢?
原因就在于应用程序所应对的业务越来越庞大、复杂,用户越来越多,没有 GC 就不能保证应用程序正常进行,而经常造成 STW 的 GC 又跟不上实际的需 求,所以才会不断地尝试对 GC 进行优化。G1(Garbage-First)垃圾回收器是在 Java7 update 4 之后引入的一个新的垃圾回收器,是当今收集器技术发展的 最前沿成果之一.
与此同时,为了适应现在不断扩大的内存和不断增加的处理器数量,进一步 降低暂停时间(pause time),同时兼顾良好的吞吐量。
官方给 G1 设定的目标是在延迟可控的情况下获得尽可能高的吞吐量,所以 才担当起“全功能收集器”的重任与期望。
G1 是一款面向服务端应用的垃圾收集器。
哪它为什么名字叫做 Garbage First(G1)呢?
在这里插入图片描述
因为 G1 是一个并行回收器,它把堆内存分割为很多不相关的区域(Region) (物理上不连续的)。使用不同的 Region 来表示 Eden、幸存者 0 区,幸存者 1 区,老年代等。
G1 GC 有计划地避免在整个 Java 堆中进行全区域的垃圾收集。G1 跟踪各 个 Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时 间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收 价值最大的 Region.
由于这种方式的侧重点在于回收垃圾最大量的区间(Region),所以我们给 G1 一个名字:垃圾优先(Garbage First)。
G1(Garbage-First)是一款面向服务端应用的垃圾收集器,主要针对配备 多核 CPU 及大容量内存的机器,以极高概率满足 Gc 停顿时间的同时,还兼具 高吞吐量的性能特征。
G1 收集器可以 “ 建立可预测的停顿时间模型 ”,它维护了一个列表用 于记录每个 Region 回收的价值大小(回收后获得的空间大小以及回收所需时 间的经验值),这样可以保证 G1 收集器在有限的时间内可以获得最大的回收 效率。
如下图所示,G1 收集器收集器收集过程有初始标记、并发标记、最终标记、 筛选回收,和 CMS 收集器前几步的收集过程很相似:
在这里插入图片描述

  1. 初始标记:标记出 GC Roots 直接关联的对象,这个阶段速度较快,需 要停止用户线程,单线程执行。
  2. 并发标记:从 GC Root 开始对堆中的对象进行可达新分析,找出存活 对象,这个阶段耗时较长,但可以和用户线程并发执行。
  3. 最终标记:修正在并发标记阶段引用户程序执行而产生变动的标记记录。
  4. 筛选回收:筛选回收阶段会对各个 Region 的回收价值和成本进行排序,根据用户所期望的 GC 停顿时间来指定回收计划(用最少的时间来回收包 含垃圾最多的区域,这就是 Garbage First 的由来——第一时间清理垃圾最多 的区块),这里为了提高回收效率,并没有采用和用户线程并发执行的方式,而 是停顿用户线程。
    适用场景: 要求尽可能可控 GC 停顿时间;内存占用较大的应用。可以用-XX:+UseG1GC使用 G1 收集器,jdk9 默认使用 G1 收集器。

小结:

垃圾回收器

比较底层,了解垃圾回收器的一些种类及实现.

垃圾回收器(具体实现垃圾回收的收集器名称)

垃圾回收器分类

按线程数分,可以分为串行垃圾回收器和并行垃圾回收器

按照工作模式分,可以分为并发式垃圾回收器和独占式垃圾回收器

按工作的内存区间分,又可分为年轻代垃圾回收器和老年代垃圾回收器

垃圾回收器的性能指标

吞吐量:运行用户代码的时间占总运行时间的比例(总运行时间:程序的运

行时间+内存回收的时间)

垃圾收集开销:垃圾收集所用时间与总运行时间的比例。

暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。

收集频率:相对于应用程序的执行,收集操作发生的频率。

内存占用:Java 堆区所占的内存大小。

快速:一个对象从诞生到被回收所经历的时间。


到此,JVM虚拟机部分已经学习完毕,下一个阶段我们将进入框架的进阶。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值