JVM工作原理与实战(四十一):ShenandoahGC原理

2024-03-01 09:36

本文主要是介绍JVM工作原理与实战(四十一):ShenandoahGC原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

专栏导航

JVM工作原理与实战

RabbitMQ入门指南

从零开始了解大数据


目录

专栏导航

前言

一、ShenandoahGC介绍

二、ShenandoahGC 1.0版本

三、ShenandoahGC 2.0版本

四、ShenandoahGC执行流程

总结


前言

JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了ShenandoahGC、ShenandoahGC 1.0版本、ShenandoahGC 2.0版本、ShenandoahGC执行流程等内容。


一、ShenandoahGC介绍

ShenandoahGC与ZGC(Z垃圾收集器)在设计上存在着显著的差异。相较于ZGC的全新开发,ShenandoahGC在很大程度上是基于G1垃圾收集器的源代码进行改造的。因此,在算法选择、数据结构定义等多个方面,ShenandoahGC与G1展现出了很高的相似性。

  • ShenandoahGC在区域划分上沿用了G1的设计理念,确保了内存管理的有效性和高效性。

  • ShenandoahGC并未采用着色指针技术,而是通过优化对象头部的设计来实现并发转移过程。这种设计策略不仅简化了实现过程,同时也确保了垃圾收集器在高并发环境下的稳定运行。

  • ShenandoahGC目前存在两个主要版本:1.0版本和2.0版本。其中,1.0版本被集成在JDK8和JDK11中,而自后续版本的JDK起,均采用了更为先进和稳定的2.0版本。这种版本迭代不仅反映了技术的不断进步,也确保了ShenandoahGC能够持续适应和满足不断变化的应用需求。

二、ShenandoahGC 1.0版本

在ShenandoahGC的1.0版本中,为了支持其并发转移机制,每个对象的前8个字节被扩展,增加了一个前向指针(Forwarding Pointer)。这个前向指针的作用是指向转移之后的对象;如果转移尚未完成,它将指向对象本身。

在转移阶段进行时,转移前的对象和转移后的对象会同时存在于内存中。当应用程序线程尝试访问这些数据时,ShenandoahGC会利用读前屏障(Read Barrier)机制,通过前向指针定位到转移后的对象,并读取该对象的数据。

对于写入操作,ShenandoahGC采用了写前屏障(Write Barrier)。在写入数据前,写前屏障会检查对象头部的Mark Word中的GC状态。如果GC状态为0,表示当前没有垃圾回收过程正在进行,线程可以直接进行写入操作。如果GC状态不为0,则根据状态值确定当前垃圾回收的具体阶段,并可能要求用户线程执行与垃圾回收相关的任务。

然而,1.0版本的设计也存在一些显著的缺点:

  • 内存占用增加:由于每个对象都需要额外的8个字节来存储前向指针,这导致整体对象内存占用显著增加,通常会增加5%到10%的空间开销。
  • 读屏障性能开销:在读前屏障中加入了复杂的指令处理逻辑,这可能会增加处理器的负担,从而影响应用程序的整体性能。

三、ShenandoahGC 2.0版本

为了解决这些问题,ShenandoahGC的2.0版本对前向指针的位置进行了优化,仅在转移阶段将其临时放入Mark Word中,从而减少了内存占用和读屏障的性能开销。这种改进使得ShenandoahGC在保持高效垃圾收集的同时,也更好地适应了不同的应用场景。

四、ShenandoahGC执行流程

  • 初始标记(STW)阶段:在这一阶段,所有的用户线程都会被暂停。ShenandoahGC会标记所有由Gc Roots直接引用的对象为存活状态。由于此阶段涉及的对象数量相对较少,因此造成的停顿时间通常非常短暂,从而最大限度地减少了应用程序的暂停时间。
  • 并发标记阶段:此阶段是与用户线程并发执行的,即垃圾收集器与用户线程同时运行。在这个阶段,ShenandoahGC会遍历堆上的所有对象,通过跟踪对象的引用关系,标记出所有可达的存活对象。为了加速这一过程,用户线程也会协助进行对象的标记工作。
  • 标记结束(STW)阶段:当并发标记阶段完成后,会进入另一个短暂的STW事件。这一阶段主要用于进行一些整理性的工作,例如处理那些在并发标记阶段未被标记的对象(即被认定为垃圾的对象),并为下一个阶段(并发转移)做好准备。
  • 并发转移阶段:此阶段同样是与用户线程并发执行的。在这个阶段,ShenandoahGC会将标记为存活的对象从旧的内存区域转移到新的内存区域中。这样做的好处是可以减少内存碎片,并提高未来垃圾收集的效率。
  • 并发重映射阶段:最后一个阶段是并发重映射。在这个阶段,ShenandoahGC会遍历所有的引用,将那些原本指向旧对象的引用更新为指向新对象。这样做可以确保应用程序在继续执行时,能够正确地访问到已经被移动的对象。

通过上述五个阶段的协同工作,ShenandoahGC能够在保持低延迟的同时,有效地管理内存并进行垃圾回收。

并发转移阶段的并发问题

在并发转移阶段,ShenandoahGC面临一个关键的并发问题。当用户线程协助进行对象转移的同时,ShenandoahGC线程也可能发现同一个对象需要被复制。在这种情况下,为了确保数据的一致性和完整性,ShenandoahGC会尝试使用类似比较并交换(CAS, Compare-And-Swap)的机制来写入前向指针。CAS是一种原子操作,它允许线程在写入共享数据之前先检查该数据的当前值。只有当当前值与预期值相匹配时,写入操作才会执行。这确保了只有一个线程能够成功修改前向指针,从而避免了并发冲突。如果CAS操作失败,即当前值与预期值不匹配,那么执行CAS操作的线程会放弃当前的转移操作,并允许其他线程尝试执行。

通过这种机制,ShenandoahGC在并发转移阶段能够确保数据的一致性和完整性,同时保持高并发性能。它允许用户线程和垃圾收集线程同时工作,从而提高了整体的系统吞吐量。


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了ShenandoahGC、ShenandoahGC 1.0版本、ShenandoahGC 2.0版本、ShenandoahGC执行流程等内容,希望对大家有所帮助。

这篇关于JVM工作原理与实战(四十一):ShenandoahGC原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/762003

相关文章

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

java中long的一些常见用法

《java中long的一些常见用法》在Java中,long是一种基本数据类型,用于表示长整型数值,接下来通过本文给大家介绍java中long的一些常见用法,感兴趣的朋友一起看看吧... 在Java中,long是一种基本数据类型,用于表示长整型数值。它的取值范围比int更大,从-922337203685477

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte