为 Java 开疆扩土的 ZGC 下

简介: 为 Java 开疆扩土的 ZGC 下

7.5 并发转移算法

转移就是将标记之后的存活对象使用复制算法转移到另外一个页面。

(1)并发转移准备

分析最有价值 GC 分页<无 STW> 。

(2)初始转移

转移初始标记的存活对象同时做对象重定位<有 STW>。

对应的初始标记,只转移对象 A。并且指针颜色发生了变化,完成了重定位,变成蓝色指针 remapped。初始转移指针直接就修改了,而且初始转移是 STW 的,因此不存在新旧地址的说法。

(3)并发转移

对转移并发标记的存活对象做转移<无STW>,由于该阶段业务线程是运行的,因此需要通过转发表来记录新旧地址的映射。转移对象和转发表记录的插入是需要做原子操作的。

(4)复制完之后,清除小页面A

(5)进入下一次垃圾回收周期

假设在两次 GC 中间创建了一个对象 E。新创建的对象的指针是蓝色的。

(6)第二次初始标记,使用M1(红色

(7)第二次并发标记,上一次并发转移的对象需要做重定位

也就是对象转移和删除转发表记录做原子操作。A 指向 B 的指针做修正,同时 A 指向E的指针也要变成 M1 红色。

八、ZGC的触发机制

(1)预热规则

JVM 启动预热,如果从来没有发生过 GC,则在堆内存使用超过 10%、20%、30% 时,分别触发一次 GC,以收集 GC 数据。

(2)基于分配速率的自适应算法

最主要的 GC 触发方式(默认方式),其算法原理可简单描述为”ZGC 根据近期的对象分配速率以及 GC 时间,计算出当内存占用达到什么阈值时触发下一次 GC”。通过 ZAllocationSpikeTolerance 参数控制阈值大小,该参数默认 2,数值越大,越早触发 GC。日志中关键字是“Allocation Rate”。

(3)基于固定时间间隔

通过 ZCollectionInterval 控制,适合应对突增流量场景。流量平稳变化时,自适应算法可能在堆使用率达到 95% 以上才触发 GC。流量突增时,自适应算法触发的时机可能会过晚,导致部分线程阻塞。我们通过调整此参数解决流量突增场景的问题,比如定时活动、秒杀等场景。

(4)主动触发规则

类似于固定间隔规则,但时间间隔不固定,是 ZGC 自行算出来的时机,我们的服务因为已经加了基于固定时间间隔的触发机制,所以通过 -ZProactive 参数将该功能关闭,以免 GC 频繁,影响服务可用性。

(5)阻塞内存分配请求触发

当垃圾来不及回收,垃圾将堆占满时,会导致部分线程阻塞。我们应当避免出现这种触发方式。日志中关键字是“Allocation Stall”。

(6)外部触发

代码中显式调用 System.gc() 触发。日志中关键字是“System.gc()”。

(7)元数据分配触发

元数据区不足时导致,一般不需要关注。日志中关键字是“Metadata GC Threshold”。

九、ZGC 参数设置

  • 堆大小 :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 的抢占开销,可根据生产情况调整。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
19天前
|
存储 Java 测试技术
Java 21革命性升级:探索分代ZGC的性能奇迹
Java 21革命性升级:探索分代ZGC的性能奇迹
34 0
|
消息中间件 算法 JavaScript
为 Java 开疆扩土的 ZGC 上
为 Java 开疆扩土的 ZGC 上
|
Java 容器
Java(JDK)13新特性之ZGC Uncommit Unused Memory
Java(JDK)13新特性之ZGC Uncommit Unused Memory
131 0
|
存储 自然语言处理 算法
Java最前沿技术——ZGC
Java最前沿技术——ZGC
547 0
|
算法 Oracle 前端开发
牛逼!全网最全代表Java未来的ZGC深度剖析
JAVA程序最爽的地方是它的GC机制,开发人员不需要关注内存申请和回收问题。同时,JAVA程序最头疼的地方也是它的GC机制,因为掌握JVM和GC调优是一件非常困难的事情。在ParallelOldGC、CMS、G1之后,JDK11带来的全新的「ZGC」为我们解决了什么问题?Oracle官方介绍它是一个Scalable、Low Latency的垃圾回收器。所以它的目的是「降第停顿时间」,由此会导致吞吐量会有所降低。吞吐量降低问题不大,横向扩展几台服务器就能解决问题了啦。在全面介绍ZGC介绍,先统计一下大家线上环境在用什么垃圾回收器:
牛逼!全网最全代表Java未来的ZGC深度剖析
|
算法 Java 测试技术
Java 12 与Java 13 新特性预览:Switch表达式、GC新垃圾回收算法、低延时GC、ZGC改进等
Java 12 与Java 13 新特性预览:Switch表达式、GC新垃圾回收算法、低延时GC、ZGC改进、文本块等
8232 0
|
3天前
|
Java 开发者 UED
掌握Java多线程编程:从基础到高级
【5月更文挑战第31天】本文深入探讨了Java多线程编程的核心概念,包括线程的创建、生命周期、同步机制以及高级并发工具。通过实际示例和代码片段,读者将学会如何有效地管理和协调线程,以编写高效且稳定的并发应用程序。
|
3天前
|
安全 Java 调度
Java语言多线程编程技术深度解析
Java语言多线程编程技术深度解析
170 1
|
3天前
|
存储 安全 Java
深入理解Java并发编程:线程安全与锁机制
【5月更文挑战第31天】在Java并发编程中,线程安全和锁机制是两个核心概念。本文将深入探讨这两个概念,包括它们的定义、实现方式以及在实际开发中的应用。通过对线程安全和锁机制的深入理解,可以帮助我们更好地解决并发编程中的问题,提高程序的性能和稳定性。
|
4天前
|
缓存 监控 安全
Java的线程池和线程安全
Java的线程池和线程安全