为 Java 开疆扩土的 ZGC 下

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 为 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日志并进行多维度分析。
相关文章
|
7月前
|
存储 算法 Java
Java ZGC 深度剖析及其在构建低延迟流系统中的实践心得
AutoMQ 基于 ZGC 进行了一系列调优,以获得更低的延迟。在本文中,我们将详细介绍 ZGC 的工作原理,以及如何通过调整和优化 ZGC 的配置来实现更低的延迟,从而提高 Java 应用程序的性能和响应能力。
81 2
Java ZGC 深度剖析及其在构建低延迟流系统中的实践心得
|
7月前
|
Java Docker 容器
Java演进问题之ZGC的优点和缺点如何解决
Java演进问题之ZGC的优点和缺点如何解决
|
7月前
|
存储 算法 Java
Java ZGC 深度剖析及其在构建低延迟流系统中的实践心得
Java ZGC 深度剖析及其在构建低延迟流系统中的实践心得
42 0
Java ZGC 深度剖析及其在构建低延迟流系统中的实践心得
|
7月前
|
Ubuntu Java Linux
Java演进问题之Java 16对元空间优化如何解决
Java演进问题之Java 16对元空间优化如何解决
|
9月前
|
存储 Java 测试技术
Java 21革命性升级:探索分代ZGC的性能奇迹
Java 21革命性升级:探索分代ZGC的性能奇迹
261 0
|
消息中间件 算法 JavaScript
为 Java 开疆扩土的 ZGC 上
为 Java 开疆扩土的 ZGC 上
|
存储 自然语言处理 算法
Java最前沿技术——ZGC
Java最前沿技术——ZGC
674 0
|
Java 容器
Java(JDK)13新特性之ZGC Uncommit Unused Memory
Java(JDK)13新特性之ZGC Uncommit Unused Memory
194 0
|
算法 Oracle 前端开发
牛逼!全网最全代表Java未来的ZGC深度剖析
JAVA程序最爽的地方是它的GC机制,开发人员不需要关注内存申请和回收问题。同时,JAVA程序最头疼的地方也是它的GC机制,因为掌握JVM和GC调优是一件非常困难的事情。在ParallelOldGC、CMS、G1之后,JDK11带来的全新的「ZGC」为我们解决了什么问题?Oracle官方介绍它是一个Scalable、Low Latency的垃圾回收器。所以它的目的是「降第停顿时间」,由此会导致吞吐量会有所降低。吞吐量降低问题不大,横向扩展几台服务器就能解决问题了啦。在全面介绍ZGC介绍,先统计一下大家线上环境在用什么垃圾回收器:
牛逼!全网最全代表Java未来的ZGC深度剖析
|
2天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
33 14

热门文章

最新文章