JVM系统优化实践(24):ZGC(一)

您好,这里是「码农镖局」掘金小站,欢迎您来,欢迎您再来~


截止到目前,算上ZGC,Java一共有九种类型的GC,它们分别是:

1、Serial GC 串行/作用于新生代/复制算法/响应速度优先/适用于单CPU下的client模式

2、ParNew GC 并行/作用于新生代/复制算法/响应速度优先/多CPU的Server模式与CMS配合使用

3、Parallel GC 并行/作用于新生代/复制算法/吞吐量优先/适用于后台运算且不需要太多交互

4、Serial Old GC 串行/作用于老年代/标记-整理算法/响应速度优先/单CPU下的Client模式

5、Parallel Old GC 并行/作用于老年代/标记-整理算法/吞吐量优先/适用于后台运算且不需要太多交互

6、CMS GC 并行/作用于老年代/标记-清除算法/响应速度优先/适用于互联网或B/S业务

7、G1 GC 并行/新生或老年代/标记-整理算法+复制算法/响应速度优先/面向服务端应用

8、Epsilon GC A No-Op GC

9、The Z GC 并发/单代/标记-整理算法+复制算法/响应速度优先/面向大数据应用

ZGC之前,下面几种GC算法是Java的主流。

1、CMS GC(JDK1.4)

2、ParNew GC(JDK1.6)

3、G1 GC(JDK1.8)

而JDK11采用了全新的GC算法。官方的介绍说它是一个Scalable和Low-Latency的GC(可以在OpenJDK官网上查JEP333)。

ZGC野心极大,其诞生之初的目标就是:

1、支持TB级别的堆内存(最大4TB)

2、最大GC停顿时间不超过10ms,且不随着堆的大小而变化

3、GC停顿期间,吞吐量降低不超过15%

4、可伸缩、低延迟

不同于以往任何的那种修修补补式的GC,ZGC不是从过去GC算法优化来的,而是全新的,JDK11的ZGC只能运行在Linux64位操作系统中(JDK14可以运行于Windows和Mac系统)。

它采用单代模型,没有了年轻代、老年代的划分,也就没有了Minor GC和Major GC的区别。

1、Region Based GC,和G1类似,但有更加灵活的region size schema,这也正是能处理TB即堆内存的原因

2、Partial Compaction,和G1一样的部分压缩

3、Colored Object Pointer,染色对象指针,使用三色标记实现对象清理

4、Multi-Mapping,内存多重映射

5、使用Load Barrier(读屏障)技术修正GC扫描结果

6、Concurrent,ZGC几乎总是以并发的形式完成所有的工作

下面一个一个来说一下。

关于单代模型:

以前的GC模型之所以分代,是源于对象生命周期极短的假设。

实现分代模型非常麻烦,为了判断是年轻代还是老年代,G1通过Remembered Set记录Region对象之间的双向引用关系,这种跟踪跨代引用的任务特别繁重。所以ZGC的做法是控制停顿阶段做的事情不和堆中的对象产生直接关联,所有在堆上进行的扫描、分配、复制等操作都是并发的,通过扫描整个堆和染色指针技术,ZGC成功去除了Remembered Set。

关于Region区域:

和G1一样,都是基于内存Region设计的GC。但它和G1固定大小的Region不同,ZGC中每个Region大小分为3类:2MB、32MB、N×32MB这几种「规格」:

1、容量2MB的Small Page存放 < 256KB的小对象

2、容量32MB的Medium Page存放 >= 256KB 且 < 4MB的对象

3、容量N×32MB的Large Page存放 >= 4MB的大对象,每个Page只放一个对象

ZGC Region的核心亮点就是动态:动态地创建和销毁,动态地决定Region的大小。

Region区域看起来就想这样的:

关于部分压缩:

以前的ParallelOldGC、CMS,无论老年代有多大,都会进行整体压缩,从而Old区越大,导致停顿时间越长。而G1和ZGC是基于Region实现的,因此只会选择部分Region进行回收,这一点G1和ZGC是一样的。

关于染色指针:

ZGC的一个核心概念就是染色指针,这里是借用一个形象的说法,并非是真的给指针"染色",它是指在GC时标记哪些对象是可回收的,即GC Roots过程。传统HopSpot虚拟机的标记实现方案是直接将标记记录在对象头部信息上,再把标记信息记录在与对象相互独立的数据结构上,如G1的Remembered Set。而ZGC是直接把标记信息记录在引用对象的指针上,这是一种直接将少量的额外信息存储在指针上的技术。目前在64位的Linux系统中,高18位预留不能使用,剩余的46位最大可支持64TB的内存空间。

ZGC将46位中的高4位取出来,用于存储染色标识信息(Finalizable、Remapped、Marked1、Marked0),用剩余的42位地址来管理4TB内存空间。

1、Finalizable:表示对象是否只能通过finalize()方法访问,其他途径是访问不了的

2、Remapped:表示对象是否已被重新映射,即是否已指向新的地址

3、Marked1、Marked0:表示对象的三色标记状态,对象是否已被标记

之所以使用两个Marked0和Marked1标记,是因为每个GC周期开启时,会交换使用的标记位。


感谢您的大驾光临!欢迎骚扰,不胜荣幸~

相关推荐
重生之我要进大厂12 分钟前
LeetCode 876
java·开发语言·数据结构·算法·leetcode
_祝你今天愉快15 分钟前
技术成神之路:设计模式(十四)享元模式
java·设计模式
小筱在线1 小时前
SpringCloud微服务实现服务熔断的实践指南
java·spring cloud·微服务
luoluoal1 小时前
java项目之基于Spring Boot智能无人仓库管理源码(springboot+vue)
java·vue.js·spring boot
ChinaRainbowSea1 小时前
十三,Spring Boot 中注入 Servlet,Filter,Listener
java·spring boot·spring·servlet·web
小游鱼KF1 小时前
Spring学习前置知识
java·学习·spring
扎克begod1 小时前
JAVA并发编程系列(9)CyclicBarrier循环屏障原理分析
java·开发语言·python
青灯文案11 小时前
SpringBoot 项目统一 API 响应结果封装示例
java·spring boot·后端
我就是程序猿1 小时前
tomcat的配置
java·tomcat
阳光阿盖尔1 小时前
EasyExcel的基本使用——Java导入Excel数据
java·开发语言·excel