G1和ZGC垃圾回收器学习

前言

​ 随着JDK17的占有率不断升高和SpringBoot3最低支持JDk17,JDK17很大概率会成为大家后续升级的一个选择,而JDK17上最重要的垃圾回收器G1和ZGC,也就显得格外重要。大家提前了解或者学习一下肯定是有用的。

​ 本篇文章也默认大家了解一些垃圾回收器的知识,也不再赘述JDK8上大家比较熟悉的垃圾回收器原理和流程。

G1垃圾回收器

​ 垃圾优先(G1)垃圾收集器针对多处理器机器,可扩展到大量内存。它试图以高概率满足垃圾收集暂停时间目标,同时实现高吞吐量,几乎不需要配置。G1旨在使用当前目标应用程序和环境提供最佳的延迟和吞吐量平衡,其特点包括:

  • 堆大小可达数十GB或更大,其中超过50%的Java堆被实时数据占用。
  • 对象分配和提升的速率可能会随时间变化而显着变化。
  • 堆中存在大量碎片。
  • 可预测的暂停时间目标不超过几百毫秒,避免长时间的垃圾收集暂停。

​ 这在应用程序运行时使用一个或多个垃圾收集线程时最为明显。因此,与吞吐量收集器相比,虽然G1收集器的垃圾收集暂停时间通常要短得多,但应用程序的吞吐量也稍微较低。

​ 上面就是官网对于G1的介绍,不难看出G1有几个特点。适合大内存、几乎不需要配置、可以预测STW时间、吞吐量要略低。

内存布局

​ G1的内存布局和之前的有一些不太一样,但是还是保留了垃圾分代的特点。内存布局如下图:

jsgct_dt_004_grbg_frst_hp

G1将内存分为不同的region,每个region大小相同。其中主要包含了四种不同的区域。年轻代Eden(图中未标字母的红色区域)、幸存者区域Suivivor(图中标有S的区域)、老区域Old(图中未标字母的蓝色区域)、大对象区域Humongous(图中标H的大块区域)。

回收流程

​ G1回收流程主要是两个阶段交替。young-only阶段和Space-reclamation阶段(也叫混合GC)。具体的交替图如下:

jsgct_dt_001_grbgcltncyl

  1. young-only阶段是只处理年轻代的一个阶段,包含了以下流程。
  • Concurrent Start:这种类型的收集在执行普通的年轻代收集的同时,还开始了标记过程。并发标记确定了老年代区域中当前可达(活动)的所有对象,以便在接下来的空间回收阶段保留这些对象。标记过程在两个特殊的停顿中完成:Remark和Cleanup。并发启动暂停还可能确定是否要继续Remark阶段,在这种情况下,会发生一个短暂的并发标记撤销阶段,然后继续进行年轻代阶段。同时,在这种情况下,不会发生Remark和Cleanup。要注意,本阶段类似CMS垃圾回收器的并发标记,不会产生STW。
  • Remark:这个阶段会STW,执行引用处理和类卸载,回收完全空的区域并清理内部数据结构。在Remark和Cleanup之间,G1会计算信息,以便稍后能够并发地回收选定的老年代区域中的空闲空间,这将在Cleanup阶段中完成。
  • Cleanup:这个阶段也会STW,同时,该阶段也决定是否实际进行Space-reclamation阶段。如果后续需要进行Space-reclamation阶段,young-only阶段将以一次准备Space-reclamation阶段回收为结束。
  1. Space-reclamation阶段会伴随多次young-only阶段,除了年轻代区域外,还会疏散一组老年代区域中的活动对象。这些收集也称为混合收集。当G1确定疏散更多的老年代区域不会产生足够的空闲空间时,Space-reclamation阶段结束。

备注:

  • young-only阶段可能不会进行垃圾回收,如果计算垃圾回收的耗时远小于设定的值,会积攒多次最后一块垃圾回收。
  • young-only阶段只会回收年轻代区域和大对象区域,Space-reclamation阶段不仅包含了这两个,还有老年代区域。
  • G1的区域回收是使用复制算法,将region内的数据整理后复制到新的region中,当前region直接清除。
  • 如果G1尝试垃圾收集后,内存还是很紧张,以至于无法找到多余的空间进行复制迁移时,会触发Full GC,这种GC是单线程的,会很慢。

​ 上面的流程可能一部分知识有误,因为能力有限,翻译过来也存在一些不通的情况。欢迎大家指正。

参数和最佳实践

​ G1的一些重要参数如下:

Option and Default ValueDescription
-XX:MaxGCPauseMillis=200最大暂停时间的目标。
-XX:GCPauseTimeInterval=<ergo>最大STW间隔的目标。默认情况下G1不设定任何目标,允许G1在极端情况下连续执行垃圾收集。
-XX:ParallelGCThreads=<ergo>垃圾收集暂停期间的最大并行工作线程数。这个数值是根据虚拟机所在计算机上可用的线程数量来确定的:如果可用于进程的CPU线程数小于或等于8,则使用该数量。否则,将大于8的线程数的五分之八加到最终的线程数中。
在每次暂停开始时,最大使用的线程数还受到其他参数限制:G1不会使用超过-XX:HeapSizePerGCThread的线程数
-XX:ConcGCThreads=<ergo>用于并发工作的最大线程数。默认情况下,该值为-XX:ParallelGCThreads除以4。
-XX:+G1UseAdaptiveIHOP
-XX:InitiatingHeapOccupancyPercent=45
控制初始堆占用的。默认值表明自适应已开启,并且在最初的几个收集周期中,G1将使用老年代45%的作为标记开始阈值。
-XX:G1HeapRegionSize=<ergo> 堆区域的大小。默认值基于最大堆大小,并计算出大约2048个区域,然后相除得到这个值。用户指定的大小必须是2的幂次方,有效值范围为1到512 MB。
-XX:G1NewSizePercent=5
-XX:G1MaxNewSizePercent=60
年轻代的总大小,在这两个值之间变化,以当前使用的 Java 堆的百分比表示。
-XX:G1HeapWastePercent=5垃圾回收候选中允许的未回收空间。如果垃圾回收候选列表中的可用空间低于该值,G1将停止Space-reclamation阶段。
-XX:G1MixedGCCountTarget=8Space-reclamation阶段在一系列收集中的预计持续时间。
-XX:G1MixedGCLiveThresholdPercent=85在Space-reclamation阶段中,如果老年代区域的存活对象占用率高于这个百分比,那么这些区域将不会被回收。

<ergo>代表这个值需要根据实际情况做判断。

​ 官方对于G1的最佳实践没有说太多,对于一般应用的建议也是使用默认值即可,不怎么需要调整,因为一些参数会在G1运行中自我调整。使用过程中只需要按照大家的要求设置期望暂停时间和最大堆大小即可。然而大家需要知道的是:G1在默认配置中的目标既不是最大吞吐量也不是最低延迟,而是在高吞吐量下提供相对较小、均匀的暂停。并且,G1回收堆空间的机制和暂停时间控制会在应用程序线程和空间回收效率方面产生一些开销,这也就是大家常说的应用内存不大的话没必要考虑G1。

​ 如果需要应用高吞吐量,则可以通过使用或提供更大的堆来放宽暂停时间目标。如果延迟是主要要求,则修改暂停时间目标。不要设置-Xmn -XX:NewRatio等参数,因为这些参数会导致期望暂停时间失效。所以从JDK8迁移到JDK17时,要丢弃所有的参数配置,并且仅设置暂停时间目标和总体堆-Xmx大小-Xms。如果不满足要求,再按照上面的表格进行一些微调。

​ 当然,JVM参数不能简单的通过一两篇博客就能设置好,具体的参数配置还是要结合GC的日志和对于应用的期望。本人这一块实践也比较少,也欢迎大家交流和指正。如果对这一部分感兴趣,可以看看oracle的调优建议。G1垃圾调优

ZGC垃圾回收器

​ 先问两个小问题:

  • ZGC中的Z代表什么意思?
  • ZGC怎么读?“zed gee see”还是“zee gee see”?

​ 我们使用的最新的JDK为17版本,ZGC还是一个初步实现的版本,并没有做分代,虽然是简单实现,但是也足够优秀。目前网络上也都是基于这个版本写的文章,但是我看到2023年JVM语言峰会上,JDK21上的ZGC已经是较为完善的版本了,所以本次也就直接学习JDK21版本的ZGC,不再讲述低版本的ZGC。

​ 新版本的ZGC更加的强大,并且主打的就是更强,更智能,基本不需要参数的调整。下面是我整理的一些特点。

  • 支持最大16TB的堆。
  • 低延迟一毫秒到几毫秒。
  • 简单的配置(几乎不需要配置)。

​ 同时,新版本相较于ZGC的老版本也有很大的提升,具体可以看下图:

​ 可以说,吞吐量是之前的4倍,并且内存减少了75%。所以分代ZGC是未来的趋势。

内存布局

​ 内存布局和之前的ZGC不太一样,不再按照大小区分region,和G1类似,直接分为两种类型,年轻代和老年代。

image-20240306170709287
回收流程

​ 新版ZGC的运行流程如下图:

image-20240306171803976
  • 第一阶段就是并发标记,同时,这一阶段也会对上一个周期的移动的对象的引用进行重新映射。
  • 并发标记结束后会有一个STW,然后就是准备并发搬迁。这个准备阶段也会做一些类卸载的操作。
  • 最后就是并发迁移。

​ 同时,年轻代和老年代的回收也是并发的,ZGC这个版本可以说一个并发垃圾回收器。

image-20240306174428198

备注:

参数配置和实践

​ 使用分代的ZGC,需要使用下面的参数:-XX:+UseZGC -XX:+ZGenerational,只使用ZGC,可以配置为:-XX:+UseZGC

​ ZGC的参数很少,几乎不需要配置。

  • 不需要设置年轻代的大小,这个计算太复杂,并且要很有经验才能估算出一个大概值,ZGC自己做了。
  • 也不需要设置内存的回收阈值(就算堆内存满了,也可以使用原地压缩,进行原地复制,所以不会想G1出现回收失败的情况,导致Full GC)。
  • 也不需要设置年轻代多长时间转换到老年代。不同的阶段可能这个值是变化的,ZGC也帮我们做了。
  • 什么时候开始老年代的收集?这个成本模型计算很复杂,ZGC也不需要我们做了。
  • 回收时使用多少线程?ZGC回收时能动态设置线程数,也不需要我们设置参数了。

那我们需要设置什么?只有一个参数-Xmx就是堆的大小,听起来挺不错的。

技术难点

​ 技术难点因为本人能力有限,而且JDK21版本23年才出来,所以一部分的技术难点分析需要看源码才能了解透彻。这里就是简单说一下。

  • 颜色指针

img

  • 读屏障
垃圾回收器未来展望

​ 随着JDK21引入了虚拟线程的概念,这部分的垃圾回收就变的不太好处理了。因为没法找到一个时间节点去回收所有虚拟线程的垃圾。所以有了一个新的概念,线程本地GC。

结尾

​ 本次解释了目前比较新的垃圾回收器,也简单分析了一下技术上的细节,同时对于一些未来的技术做了一个小小的展望。当然,很多都是参考一些会议上的记录,本人能力有限,可能中间一些翻译和理解有错误,也欢迎大家指正。会议的资料地址:JVMLS2023

​ 就这样吧,结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/759923.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片机学到什么程度才可以去工作?

单片机学到什么程度才可以去工作? 如果没有名校或学位的加持&#xff0c;你还得再努力一把&#xff0c;才能从激烈的竞争中胜出。以下这些技能可以给你加分&#xff0c;你看情况学&#xff0c;不同行业对这些组件会有取舍: . Cortex-M内核:理解MCU内核各部件的工作机制&#…

力扣---两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

快速画流程图

使用在线工具&#xff1a;PlantUML PlantUML 官网:https://plantuml.com/ 中文官网:https://plantuml.com/zh/ 使用步骤如下&#xff1a; 1、拷贝一个完成函数&#xff1a; int func_init(const char *tag) {if (tag ! NULL) {printf("set TAG :%s", tag);}print…

webpack5零基础入门-13生产模式

1.生产模式介绍 生产模式是开发完成代码后&#xff0c;我们需要得到代码将来部署上线。 这个模式下我们主要对代码进行优化&#xff0c;让其运行性能更好。 优化主要从两个角度出发: 优化代码运行性能优化代码打包速度 2.生产模式准备 我们分别准备两个配置文件来放不同的…

python的FastAPI 快速入门

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

《算法王晓东》多处最优服务次序问题

多处最优服务次序问题 题目描述 设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti, 1≤i≤n。共有s处可以提供此项服务。应如何安排n个顾客的服务次序才能使平均等待时间达到最小? 平均等待时间是n个顾客等待服务时间的总和除以n。 算法设计&#xff1a;对于给定的n个顾…

41 物体检测和目标检测数据集【李沐动手学深度学习v2课程笔记】

目录 1. 物体检测 2. 边缘框实现 3.数据集 4. 小结 1. 物体检测 2. 边缘框实现 %matplotlib inline import torch from d2l import torch as d2ld2l.set_figsize() img d2l.plt.imread(../img/catdog.jpg) d2l.plt.imshow(img);#save def box_corner_to_center(boxes):&q…

设计模式之抽象工厂模式解析

抽象工厂模式 1&#xff09;问题 工厂方法模式中的每个工厂只生产一类产品&#xff0c;会导致系统中存在大量的工厂类&#xff0c;增加系统的开销。 2&#xff09;概述 a&#xff09;产品族 和 产品等级结构 产品等级结构&#xff1a;产品的继承结构&#xff1b; 产品族&…

通俗理解自注意力机制

自注意力机制&#xff08;Self-Attention Mechanism&#xff09; 是一种用于处理序列数据的机制&#xff0c;最初被引入到神经网络模型中&#xff0c;用于在序列数据中建立全局依赖关系。自注意力机制最常用于自然语言处理和计算机视觉领域&#xff0c;特别是在Transformer模型…

【Flutter】文件选择器(file_picker)的用法

Flutter 没有提供内置的文件选择器&#xff0c;但社区内有人贡献了一个比较完整的解决方案——file_picker。 file_picker 的 API 简洁易用&#xff0c;支持全平台&#xff08;Android / iOS / Mac / Linux / Windows&#xff09;&#xff0c;是我开发桌面应用时的首选。 这边…

HMI界面之:上位机界面设计,一文扫盲

一、什么是上位机 上位机&#xff08;Supervisory Control and Data Acquisition&#xff0c;简称SCADA&#xff09;是一种用于监控和控制工业过程的计算机系统。它通常由两个主要部分组成&#xff1a;上位机和下位机。 上位机是SCADA系统中的主要控制中心&#xff0c;负责监控…

mysql笔记:24. 主从同步环境搭建

文章目录 主从同步的基本原理主从同步的搭建步骤1. 环境准备2. 配置主服务器&#xff08;Master&#xff09;3. 配置从服务器&#xff08;Slave&#xff09;4. 测试配置5. 常见故障5.1. 主从服务器上的MySQL版本不一致导致失败&#xff1f;5.2. Slave_IO_Running状态异常&#…

使用ollama + webui 运行任意大模型

安装ollama https://hub.docker.com/r/ollama/ollama docker run -d -v ~/Documents/work/softs/docker/ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama验证安装 # 进入容器docker exec -it ollama bash # 运行大模型 ollama run llama2 # 发送请求&…

三级数据库技术考点(详解!!)

1、 答疑:【解析】分布式数据库系统按不同层次提供的分布透明性有:分片透明性;②位置透明性;③局部映像透明性&#xff0c;位置透明性是指数据分片的分配位置对用户是透明的&#xff0c;用户编写程序时只需 要考虑数据分片情况&#xff0c;不需要了解各分片在各个场地的分配情…

什么是物联网远程模块

在数字化和信息化的浪潮下&#xff0c;物联网技术正在以惊人的速度改变着我们的生活和生产方式。物联网远程模块&#xff0c;作为物联网技术的核心组件之一&#xff0c;正引领着这场变革。HiWoo Box就是这样一款出色的物联网远程模块&#xff0c;它通过支持远程透传、远程锁机、…

多进程数据库不适合作为hive的元数据库

简介 “今天发现一个比较奇怪的现象&#xff0c;因为博主不熟悉mysql&#xff0c;所以在安装hive的使用了postgresql作为hive的元数据库&#xff0c;在测试几个连接工具对hive进行链接&#xff0c;后面再测试的时候发现链接不上了&#xff0c;并且报错日志如下&#xff1a;” …

从回收站删除的文件如何恢复?图文详解(3个方法)!

“各位大佬&#xff01;从回收站删除了重要的文件后&#xff0c;有什么方法可以恢复文件吗&#xff1f;快帮帮我吧&#xff01;这些被删除的文件都是比较重要的&#xff01;” 回收站作为电脑中的一个重要工具&#xff0c;当我们误删文件后&#xff0c;通过回收站有机会快速恢复…

QT增加线程函数步骤流程

在使用线程的时候&#xff0c;不仅要关注线程开启的时机&#xff0c;同时还要关注线程安全退出&#xff0c;这样才能保证程序的健壮性&#xff0c;如果线程开启的较多&#xff0c;且开启关闭比较频繁&#xff0c;建议使用线程池来处理。开启线程有三种方式&#xff1a;第一种C的…

C语言动态内存管理(重点)

目录 1、为什么要有动态内存分配 2、malloc 和 free 2.1 malloc函数 2.2 free函数 3、calloc 和 realloc 3.1 calloc函数 3.2 realloc 函数 3.3 realloc 和 malloc 区别 3.4 realloc 函数存在的问题 4、常见的动态内存的错误 5、动态内存经典笔试题分析 6、柔…

Vue.js前端开发零基础教学(一)

目录 第一章 初识Vue.js 前言 开发的好处 一.前端技术的发展 什么是单页Web应用&#xff1f; 二. Vue的简介 三. Vue的特性 四. Vue的版本 五.常见的包管理 六.安装node环境 第一章 初识Vue.js 学习目标&#xff1a; 了解前端技术的发展 了解什么是Vue掌握使用方…