JVM-垃圾回收器-ZGC

  1. 新一代垃圾回收器ZGC的探索与实践 - 美团技术团队
  2. Main - Main - OpenJDK Wiki

介绍

        ZGC(Z Garbage Collector) 是一款性能比 G1 更加优秀的垃圾收集器。ZGC 第一次出现是在  JDK 11 中以实验性的特性引入,这也是 JDK 11 中最大的亮点。在 JDK 15 中 ZGC 不再是实验功能,可以正式投入生产使用了,使用 –XX:+UseZGC 可以启用 ZGC。

特征

  1. 停顿时间(STW)不超过10ms(JDK16是不超过1ms),且不会随着堆的大小增加而增加

      G1 300ms

  1. 理论上最大支持 16TB 的大堆,最小支持 8MB 的小堆。2048 分区,堆128G还是负担比较重
  2. 跟 G1 相比,对应用程序吞吐量的影响小于15%,吞吐量,通过扩容解决

目标

主要目标:巩固老大地址、卷其他语言!

  1. 抢C++的市场
  2. 防止被go语言等抢市场

ZGC的案例介绍

阿里(借鉴ZGC优化自己JVM)

美团(规则平台等)

58(Hbase平台)

腾讯(在线交互、竟价广告、量化交易等)

华为(毕昇JDK、大数据项目) 

堆空间分页模型(无分代)

将内存分为三种类型的页面

  1. 小型Region(Small Region):容量固定为2MB, 用于放置小于256KB的小对象。
  2. 中型Region(Medium Region):容量固定为32MB, 用于放置大于等于256KB但小于4MB的对象。
  3. 大型Region(Large Region):容量不固定, 可以动态变化, 但必须为2MB的整数倍, 用于放置4MB或以上的大对象。 和操作系统有关

页面类型

页面大小

页面内对象的大小

页面内对象对齐的粒度

小页面

2MB

小于等于256KB

MinObjectAlignmentInBytes

中页面

32MB

在256KB和4MB之间

4KB

大页面

X*MB,受操作系统控制

大于4MB

2MB

ZGC对于不同页面回收的策略也不同。简单地说,小Region优先回收;中Region和大Region则尽量不回收 

 为什么这么设计?

Linux Kernel 2.6引入的标准大页(huge page)

标准大页(huge page)是Linux Kernel 2.6引入的目的是通过使用大页内存来取代传统的4KB内存页面,以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能

 ZGC的内存布局

        应用程序创建对象时,首先在堆空间申请一个虚拟地址,但该虚拟地址并不会映射到真正的物理地址。ZGC同时会为该对象在M0、M1和Remapped地址空间分别申请一个虚拟地址,且这三个虚拟地址对应同一个物理地址,但这三个空间在同一时间有且只有一个空间有效。ZGC之所以设置三个虚拟地址空间,是因为它使用“空间换时间”思想,去降低GC停顿时间。“空间换时间”中的空间是虚拟空间,而不是真正的物理空间

虚拟内存映射

NUMA

统一内存访问UMA:

  • 在x86架构中,内存没有整合进CPU,需要总线来访问
  • 任何CPU访问内存的速度都是一致的,没有差异,称为统一内存访问Uniform Memor Access, UMA)
  • 当所有核都链接到一块内存上时,访问内存中任何一个区域的时间都相同

NUMA:

核访问与自己直接相连的内存区域,比访问其它区域快的多,因为访问其它区域需要通过另外一个芯片,因此被称为非一致性内存访问系统NUMA(Nonuniform Memory Access)

        UMA系统中因为核直接和内存相连,任意一个核都能访问内存中的任何地址,因此当数据存储在内存中不同位置时,UMA系统存取指令和数据更快。NUMA系统中因为内存可以连接到不同的内存上,因此具有更好的内存扩展性。

        因为在NUMA系统中想要存取不同内存上的数据时,需要核心直接交互才能实现,跨NUMA会导致几纳秒的时间浪费,因此如果程序对性能比较敏感需要将程序绑定到指定的NUMA上,以此来避免不同NUMA之间核的交互

ZGC为什么那么快?

分代模型和分区模型

•低延迟:

        ZGC的分页模型允许并发地处理内存分配和回收操作,从而减少了垃圾收集的停顿时间。相比之下,分代模型需要在不同代之间进行对象的复制或移动,可能会导致更长的停顿时间。

•内存利用率高:

        ZGC的分页模型可以动态地调整页的大小,以适应不同大小的对象。这样可以提高内存的利用率,减少内存碎片的产生。而分代模型中,不同代的内存空间是固定的,可能会导致内存碎片的问题。

•可伸缩性:

        ZGC的分页模型允许将堆内存划分为多个页区,并且每个页区都有独立的垃圾收集线程。这样可以实现垃圾收集的并行性,提高系统的可伸缩性和吞吐量。而分代模型中,不同代的垃圾收集是串行或并发-串行的,可能无法充分利用多核处理器的性能。

•适应大内存堆:

        ZGC的分页模型可以有效地管理大内存堆。它可以根据需要动态地增加或减少页的数量,以适应大内存堆的需求。而分代模型中,不同代的内存空间是固定的,无法有效地管理大内存堆。

GC标记信息位置的变化

        传统垃圾回收器通过扫描堆中的对象(扫描堆空间是很慢的),根据对象头中的可达性标记信息,来确定对象是否应该被回收。

        ZGC不直接依赖于对象头中的信息来进行垃圾回收决策,而是把GC信息存在内存引用地址上。GC时通过扫描栈上的内存引用指针来确定对象的引用关系和可达性,从而来判断对象是否应该被回收。       

垃圾回收流程

标记阶段(标识垃圾)
转移阶段(对象复制或移动)

初始阶段:在ZGC初始化之后,此时地址视图为Remapped,程序正常运行,在内存中分配对象,满足一定条件后垃圾回收启动。

初始标记:初始标记只需要扫描所有GC Roots,其处理时间和GC Roots的数量成正比,停顿时间不会随着堆的大小或者活跃对象的大小而增加。

并发标记:扫描剩余的所有对象,这个处理时间比较长,所以走并发,业务线程与GC线程同时运行。但是这个阶段会产生漏标问题。

基于上一步的绿色节点开始并发标记:所有访问到的活对象都标记为绿色,指针也是绿色

再标记:主要处理漏标对象,通过SATB算法解决(G1中的解决漏标的方案)

主要解决并发标记过程中的漏标问题,活的对象和指针仍然是绿色,可以发现,再标记之后,仍然是蓝色的对象就是垃圾对象

  1. 并发转移准备:分析最有价值GC分页哪些区域有垃圾,哪些需要回收等等
  2. 初始转移:转移初始标记的存活对象同时做对象重定位,初始标记的对象,就是初始转移的对象,GC ROOTS

并发转移:对转移并发标记的存活对象做转移,经过并发标记和再标记调整之后的对象,就是并发转移的对象

在两次GC中间业务线程如何访问没有做完重定位的对象?

参数

If you're trying out ZGC for the first time, start by using the following GC options:

-XX:+UseZGC -XX:+ZGenerational -Xmx<size> -Xlog:gc

For more detailed logging, use the following options:

-XX:+UseZGC -XX:+ZGenerational -Xmx<size> -Xlog:gc*

堆大小:Xmx。当分配速率过高,超过回收速率,造成堆内存不够时,会触发 Allocation Stall,这类 Stall 会减缓当前的用户线程。因此,当我们在GC日志中看到 Allocation Stall,通常可以认为堆空间偏小或者 concurrent gc threads 数偏小。

GC 触发时机:ZAllocationSpikeTolerance, ZCollectionInterval。ZAllocationSpikeTolerance 用来估算当前的堆内存分配速率,在当前剩余的堆内存下,ZAllocationSpikeTolerance 越大,估算的达到 OOM 的时间越快,ZGC 就会更早地进行触发 GC。ZCollectionInterval 用来指定 GC 发生的间隔,以秒为单位触发 GC。

GC 线程:ParallelGCThreads, ConcGCThreads。ParallelGCThreads 是设置 STW 任务的 GC 线程数目,默认为 CPU 个数的 60%;ConcGCThreads 是并发阶段 GC 线程的数目,默认为 CPU 个数的 12.5%。增加 GC 线程数目,可以加快 GC 完成任务,减少各个阶段的时间,但也会增加 CPU 的抢占开销,可根据生产情况调整。

General GC Options

ZGC Options

ZGC Diagnostic Options (-XX:+UnlockDiagnosticVMOptions)

-XX:MinHeapSize, -Xms

-XX:InitialHeapSize, -Xms

-XX:MaxHeapSize, -Xmx

-XX:SoftMaxHeapSize

-XX:ConcGCThreads

-XX:ParallelGCThreads

-XX:UseDynamicNumberOfGCThreads

-XX:UseLargePages

-XX:UseTransparentHugePages

-XX:UseNUMA

-XX:SoftRefLRUPolicyMSPerMB

-XX:AllocateHeapAt

-XX:ZAllocationSpikeTolerance

-XX:ZCollectionInterval

-XX:ZFragmentationLimit

-XX:ZMarkStackSpaceLimit

-XX:ZProactive

-XX:ZUncommit

-XX:ZUncommitDelay

-XX:ZStatisticsInterval

-XX:ZVerifyForwarding

-XX:ZVerifyMarking

-XX:ZVerifyObjects

-XX:ZVerifyRoots

-XX:ZVerifyViews

-XX:ZYoungGCThreads

-XX:ZOldGCThreads

-XX:ZBufferStoreBarriers

  • 47
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值