马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
垃圾采取(Garbage Collection, GC)是 Java 捏造机(JVM)中一个至关紧张的部分,尤其是在面临差异的业务场景时,选择符合的垃圾网络器(Garbage Collector, GC)对于优化 GC 性能至关紧张。本文将详细先容 JVM 中两大类垃圾网络器:分代网络器和分区网络器,并重点分析 CMS、G1 和 ZGC 这三种垃圾网络器的工作原理、优缺点及实在用场景。
1 分代网络器
1.1 CMS(Concurrent Mark Sweep)
1.1.1 概述
CMS(Concurrent Mark Sweep)垃圾网络器是 JDK 1.5 引入的,旨在通过并发实行垃圾采取来镌汰 GC 停顿时间(Stop-The-World, STW)。它是第一个专注于镌汰 GC 停顿时间的垃圾网络器,之前的垃圾网络器要么是串行的,要么只关注体系吞吐量。CMS 采取“标志-打扫”算法,其垃圾采取过程分为四个步调:
- 初始标志(Initial Mark)
- 并发标志(Concurrent Mark)
- 重新标志(Remark)
- 并发打扫(Concurrent Sweep)
1.1.2 工作原理
初始标志阶段的重要使命是标志全部从 GC Roots 直接可达的对象。这个阶段须要 STW,但由于只标志 GC Roots 直接关联的对象,因此速率非常快。
并发标志阶段从初始标志的对象开始,遍历整个引用链,标志全部可达的对象。这个阶段不须要 STW,垃圾采取线程与用户线程并发实行。固然并发标志可以大概显着低沉停顿时间,但也带来了一些题目,比方引用厘革大概导致漏标(本应采取的垃圾未被采取)或多标(不应采取的垃圾被采取)。
重新标志阶段的重要使命是对并发标志阶段出现的题目举行校正。由于并发标志阶段大概发生引用厘革,因此须要 STW 来修正标志错误,确保垃圾采取的正确性。
并发打扫阶段将标志为垃圾的对象举行打扫。这个阶段不须要 STW,垃圾采取线程与用户线程可以并发实行,因此不会影响体系的相应时间。
1.1.3 优缺点
长处
- 并发网络:垃圾采取线程与用户线程并发实行,显着低沉了停顿时间。
- 低停顿:实用于对相应时间要求较高的应用步调,如强交互式应用。
缺点
CMS 默认启用的垃圾采取线程数为 (CPU数量 + 3)/4。当 CPU 数量较少时,垃圾采取线程占用的 CPU 资源比例较高,比方在只有 2 个 CPU 的情况下,垃圾采取线程占用到达 50%,这会显着低沉体系的吞吐量。
CMS 采取“标志-打扫”算法,会产生大量的内存碎片,导致内存空间不一连。当须要分配大对象时,大概会由于找不到一连的内存空间而触发 Full GC,从而增长体系的停顿时间。
在垃圾采取过程中,应用步调仍在不停产生垃圾,这些垃圾被称为浮动垃圾。CMS 无法在当前垃圾采取周期内处理处罚这些浮动垃圾,只能在下次 GC 时清算,这大概导致内存利用服从低沉。
1.1.4 小结
CMS 垃圾网络器通过并发实行垃圾采取,显着低沉了停顿时间,实用于对相应时间要求较高的应用场景。然而,它对 CPU 资源敏感,轻易产生内存碎片,而且无法处理处罚浮动垃圾。随着 JDK 版本的更新,CMS 在 JDK 9 中被标志为弃用,并在 JDK 14 中被移除,取而代之的是更先辈的垃圾网络器,如 G1 和 ZGC。
2 分区网络器
2.1 G1(Garbage-First Garbage Collector)
2.1.1 概述
G1(Garbage-First Garbage Collector)是 JDK 1.7 引入的垃圾网络器,并在 JDK 9 中代替了 CMS 成为默认的垃圾网络器。G1 的筹划目标是提供一种高效、可推测的垃圾采取机制,实用于大内存和低延长的应用场景。G1 具有以下五个重要属性:
2.1.2 工作原理
G1 基于分代头脑筹划,将堆内存分别为多个巨细相当的地域(Region),每个地域可以是 Eden 区、Survivor 区或 Old 区。通过 -XX:G1HeapRegionSize=n 可以设置 Region 的巨细,范围为 1MB 到 32MB。
大对象处理处罚(Humongous Region)
G1 为大对象专门分配了 Humongous 区。大对象的判定规则是:假如一个对象的巨细凌驾了一个 Region 的 50%,则会被放入 Humongous 区。比方,假如每个 Region 的巨细为 2MB,那么凌驾 1MB 的对象就会被放入 Humongous 区。假如对象非常大,大概会高出多个 Region 存放。
G1 根据各个地域的垃圾采取情况动态决定下一次垃圾采取的地域,从而制止对整个堆内存举行垃圾采取,低沉了垃圾采取的时间。
G1 采取增量方式实行垃圾采取,即不须要一次性采取整个堆空间,而是徐徐、增量地清算垃圾。这种筹划有助于控制停顿时间,尤其是在处理处罚大型堆时。
G1 支持并行垃圾采取,利用多个 CPU 加速垃圾采取的速率。这一特性在年轻代的垃圾采取(Minor GC)中尤为显着,由于年轻代的对象通常较多,采取速率较高。
在老年代的垃圾采取中,G1 利用标志-整理算法。该算法分为两个阶段:
- 标志存活对象:遍历对象图,标志全部存活的对象。
- 整理堆空间:压缩堆空间,消除内存碎片,进步内存利用率。
年轻代的垃圾采取(Minor GC)则利用复制算法,由于年轻代的对象通常是朝生夕死的,得当快速复制和清算。
只管 G1 采取了多种优化本领,但在垃圾采取过程中仍旧须要 STW。不外,G1 引入了停顿时间推测模子(Pause Prediction Model),用户可以通过 -XX:MaxGCPauseMillis 设置盼望的停顿时间(默认 200ms)。G1 会根据这个值盘算出公道的 Young GC 采取时间,并订定相应的采取筹划。
2.1.3 GC 模式
G1 中存在三种重要的 GC 模式:
- Young GC
- Mixed GC
- Full GC
2.1.3.1 Young GC
当 Eden 区的内存空间无法支持新对象的内存分配时,G1 会触发 Young GC。Young GC 采取复制算法,采取年轻代的 Region。
2.1.3.2 Mixed GC
当须要分配对象到 Humongous 地域,大概堆内存的空间占比凌驾 -XX:G1HeapWastePercent 设置的 InitiatingHeapOccupancyPercent 值时,G1 会触发一次并发标志(Concurrent Marking)。并发标志的作用是盘算老年代中有多少空间须要被采取。
当并发标志完成后,假如发现老年代中垃圾的占比到达 -XX:G1HeapWastePercent 设置的比例(默认 5%),则在下次 Young GC 后会触发 Mixed GC。Mixed GC 采取年轻代的 Region 以及一部分老年代的 Region,同样采取复制算法。
2.1.3.3 Full GC
在 Mixed GC 过程中,假如发现老年代空间仍旧不敷,且 -XX:G1HeapWastePercent 设置过低,大概会引发 Full GC。Full GC 会对整个堆举行采取,通常会导致较长的停顿时间。
2.1.4 停顿推测模子(Pause Prediction Model)
G1 的停顿推测模子是其核心特性之一。用户可以通过 -XX:MaxGCPauseMillis 设置盼望的停顿时间,G1 会根据这个值盘算出公道的 Young GC 采取时间,并订定相应的采取筹划。这种机制使得 G1 可以大概在大内存情况下提供可推测的停顿时间,实用于对延长敏感的应用场景。
2.1.5 优缺点
G1 的长处
- 可推测的停顿时间:通过停顿推测模子,用户可以设置盼望的停顿时间。
- 内存碎片较少:采取标志-整理算法,制止内存碎片题目。
G1 的缺点
2.2 ZGC(The Z Garbage Collector)
2.2.1 概述
ZGC(The Z Garbage Collector)是 JDK 11 推出的一款低延长垃圾网络器,专为大内存和低延长服务的内存管理和采取而筹划。在 SPEC jbb 2015 基准测试中,ZGC 在 128GB 的大堆下,最大停顿时间仅为 1.68 毫秒,显着优于 G1 和 CMS。ZGC 的筹划目标是在不凌驾 10 毫秒的停顿时间内,支持 TB 级内存容量,并提供险些全部的 GC 功能。
只管 ZGC 的名字中的 “Z” 并没有明确的官方界说,但它象征着对大内存和高性能的寻求,目标是支持从 8MB 到 4TB 的堆内存,未来乃至大概扩展到 16TB。
2.2.2 核心筹划目标
- 停顿时间不凌驾 10ms:ZGC 的核心目标是将停顿时间控制在 10 毫秒以内。
- 停顿时间不随堆巨细或活泼对象数量增长:无论堆内存巨细或活泼对象数量怎样厘革,ZGC 的停顿时间都能保持稳固。
- 支持大内存:ZGC 支持从 8MB 到 4TB 的堆内存,未来大概扩展到 16TB。
2.2.3 工作原理
ZGC 采取了复制算法,但在标志、转移和重定位阶段举行了庞大优化,使其可以大概实现险些完全的并发实行,从而显着低沉停顿时间。
2.2.3.1 标志阶段
标志阶段从 GC Roots 开始,分析对象的可达性,标志出全部存活的对象。与 G1 雷同,ZGC 的标志阶段也分为以下三个步调:
- 标志阶段:从 GC Roots 开始,标志全部存活的对象。
- 对象转移阶段:将存活对象复制到新的内存所在。
- 重定位阶段:调解全部指向旧所在的引用,使其指向新的对象所在。
在 G1 中,转移阶段和重定位阶段是 STW 的,这导致了较长的停顿时间。而 ZGC 通过并发实行这些阶段,极大地低沉了停顿时间。
2.2.3.2 并发实行的关键技能
ZGC 实现低停顿的关键在于以下两项技能:
- 指针染色(Colored Pointer)
- 读屏蔽(Load Barrier)
指针染色(Colored Pointer)
指针染色是一种在指针中嵌入元数据信息的技能。在 64 位体系中,ZGC 仅利用 42-45 位来存储对象的元数据信息,包罗:
- 对象是否被移动:标志对象是否在垃圾采取过程中被移动到了新的位置。
- 对象的存活状态:标志对象是否存活。
- 对象的其他状态:如对象是否被锁定或有其他特别状态。
通过在指针中嵌入这些信息,ZGC 可以在标志和转移阶段快速区分对象的状态,而无需额外的内存访问,从而进步了服从。
读屏蔽(Load Barrier)
读屏蔽是一种在步调运行时插入到对象访问利用中的特别查抄机制。当步调实行读取一个对象时,读屏蔽会触发以下利用:
- 查抄指针染色:读屏蔽起首查抄指向对象的指针的颜色信息。
- 处理处罚移动的对象:假如指针体现对象已经被移动,读屏蔽将确保返回对象的新所在。
- 确保划一性:通过这种方式,ZGC 可以大概在并发移动对象时保持内存访问的划一性,从而镌汰对应用步调停顿的须要。
读屏蔽的伪代码实现如下:
- // 伪代码示例,展示读屏障的概念性实现
- Object* read_barrier(Object* ref) {
- if (is_forwarded(ref)) {
- return get_forwarded_address(ref); // 获取对象的新地址
- }
- return ref; // 对象未移动,返回原始引用
- }
复制代码 2.2.3.3 捏造所在空间分别
ZGC 仅支持 64 位体系,并将 64 位捏造所在空间分别为多个子空间:
- 0-4TB:对应 Java 堆。
- 4TB-8TB:称为 M0 所在空间。
- 8TB-12TB:称为 M1 所在空间。
- 12TB-16TB:预留未利用。
- 16TB-20TB:称为 Remapped 空间。
当创建对象时,ZGC 会在堆空间申请一个捏造所在,并在 M0、M1 和 Remapped 空间中为该对象分别申请一个捏造所在,且这三个捏造所在都映射到同一个物理所在。在同一时间,只有一个所在空间是有用的。这种筹划通过“空间换时间”的头脑,低沉了 GC 的停顿时间。
2.2.4 并发工作过程
ZGC 的垃圾采取周期由三个 STW 停息和四个并发阶段构成:
2.2.4.1 STW 停息阶段
- 标志开始(Mark Start):初始标志 GC Roots,标志全部从 GC Root 直接可达的对象,须要短暂的 STW。
- 重新映射开始(Relocation Start):预备对象的重定位,选择将要清算的内存地域,并创建须要的数据结构,须要短暂的 STW。
- 停息竣事(Pause End):完成与该 GC 周期干系的终极清算工作,须要短暂的 STW。
2.2.4.2并发阶段
- 并发标志/重新映射(M/R):并发标志全部可达的对象,并更新指向移动对象的全部引用。
- 并发引用处理处罚(RP):处理处罚各种引用范例(如软引用、弱引用、虚引用和幽灵引用)。
- 并发转移预备(EC):确定哪些内存地域将被清算,并预备干系的数据结构。
- 并发转移(RE):将存活的对象从旧位置移动到新位置,应用步调可以在大多数垃圾采取工作举行时继承运行。
2.2.5 并发标志与重定位的优化
在传统的垃圾采取器中,标志和重定位阶段通常须要访问对象头中的存活信息,这会导致额外的内存访问开销。而在 ZGC 中,对象的存活信息直接存储在指针的第 42-45 位中,通过寄存器访问,速率比访问内存更快。这种筹划使得 ZGC 在并发标志和重定位阶段可以大概高效地处理处罚对象状态。
2.2.6 优缺点
长处
- 极低的停顿时间:停顿时间不凌驾 10ms。
- 支持大内存:支持 8MB~4TB 的堆内存。
缺点
- 仅支持 64 位体系:现在仅在 64 位体系上可用。
3 总结
CMS、G1 和 ZGC 都是为了低沉 GC 停顿时间而筹划的垃圾网络器,但它们各有优缺点。CMS 实用于对相应时间要求较高的场景,但存在内存碎片和 CPU 资源敏感的题目;G1 提供了可推测的停顿时间,实用于大内存场景,但实现复杂;ZGC 则以极低的停顿时间和对大内存的支持为特点,实用于对延长要求极高的应用场景。
根据详细的业务需求和体系情况,选择符合的垃圾网络器是优化 GC 性能的关键。
4 头脑导图
5 参考链接
深入明确 JVM 的垃圾网络器:CMS、G1、ZGC
|