当前位置: 首页 > news >正文

JVM面试(七)G1垃圾收集器剖析

概述

上一章我们说了,G1收集器,它属于里程碑式的发展,开创了面向局部收集垃圾的概念。专门针对多核处理器以及大内存的机器。在JDK9中,更是呗指定为官方的GC收集器。满足高吞吐的通知满足GC的STW停顿时间尽可能的短。

虽然现在我们看来这种“化整为零”的解题思路没有多大的创新,也很好理解,但是在运行的时候其实有很多问题。 包括但不限于如下:

  • 多个Region,对于那些跨区引用对象如何解决?
  • 并发标记的时候,怎么保证收集线程和用户线程并行?收集过程中用户改变了对象的引用关系怎么办?
  • 如何预测停顿时间?

下面我们先来完整的了解一下,然后再解答上面的问题。

分区原理

使用G1收集器时,它将整个Java堆划分成约2048个⼤⼩相同的独立Region块,每个Region块大小根据堆空间的实际大小而定,整体被控制在1MB到32MB之间,且为2的N次幂,即1MB, 2MB, 4MB, 8MB, 16MB, 32MB。
可以通过-XX:G1HeapRegionSize设定。所有的Region大小相同,且在JVM⽣命周期内不会被改变。

虽然还保留着新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region (不需要连续)的集合。通过Region的动态分配方式实现逻辑上的连续。
在这里插入图片描述

⼀个region(分区)只能属于⼀个角色,有可能为eden区、S区、老年代等, E表示为Eden区、S区表示为S1,S0区,老年代O区 空白的表示为未使用的分配的内存。H区存放巨型对象

巨型对象

在G1收集器中也有⼀个新的内存区域,称作为:Humongous (H)区(巨型对象),主要存放⼀些比较大的对象,⼀个对象大于region的⼀半时,称之为巨型对象,G1不会对巨型对象进行拷贝,回收时会考虑优先回收。
在以前收集器中,如果是⼀个大对象是直接放入到老年代中,而触发老年代GC不是很频繁,万一该大对象不是非常频繁的使用,则会非常浪费我们堆内存,为了解决这个问题在G1收集器专门弄⼀个H区存放巨型对象。(垃圾回收时,对于H区中的对象会优先回收,来提升内存使用效率)

回收流程

大致可以划分为以下四个步骤:

  • 初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。
  • 并发标记(Concurrent Marking):从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。
  • 最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。
  • 筛选回收(Live Data Counting and Evacuation):负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

示意图:
在这里插入图片描述

新生代回收

依然是分代式的回收,新生代回收主要工作就是回收Eden区和Survivor区。一旦Eden区被占满,就会触发年轻代的GC线程,只处理Eden区和部分Survivor区。因为也是要做标记-复制算法,将存活的对象放入另一个Survivor区里面。

老年代

当老年代+大对象 达到堆空间阈值的时候,就会开启并发标记(不会stw)任务。对应的配置参数:
-XX:InitiatingHeapOccupancyPercent=45%

而在并发标记过程中,用户线程变动对象引用产生的漏标问题,G1采用了初始快照算法
snapshot⼀at⼀the⼀beginning (SATB)

记忆集与卡表解决跨区引用

先了解一下什么是记忆集与卡表

记忆集是⼀种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。卡表就是记忆集的⼀种具体实现,它定义了记忆集的记录精度、与堆内存的映射关系等。

关于卡表与记忆集的关系,可以按照Java语言中HashMap与Map的关系来类比理解。

卡表的数据结构对应⼀个字节数组。CARD_TABLE的每⼀个元素都对应着其标识的内存区域中⼀块特定大小的内存块,这个 内存块被称作“卡页”(Card Page)⼀个卡页的内存中通常
包含不止⼀个对象,只要卡页内有⼀个(或更多)对象的字段存在着跨代指针,那就将对应卡表的数组元素的值标识为1,称为这个元素变脏(Dirty),没有则标识为0。在垃圾收集发生时,只要筛选出卡表中变脏的元素,就能轻易得出哪些卡页内存块中包含跨代指针,把它们加入GC Roots中⼀并扫描。

原始快照 SATB 解决不干扰用户线程

在并发标记过程中,不影响用户线程,首先要解决的是标记过程中用户引用的变动,也就是之前说过的漏标问题,CMS用的是增量更新算法,之前的章节我们说过。而G1用的是原始快照的方法。

原始快照:当对象的引用关系变动的时候,将这个变动的引用关系也记录下来。 在并发标记结束之后,再通过 这些保存下来的对象引用快照,再扫描一次。

预测停顿时间

用户通过-XX:MaxGCPauseMillis参数指定的停顿时间只意味着垃圾收集发生之前的期望值,但G1收集器要怎么做才能满足用户的期望呢?G1收集器的停顿预测模型是以衰减均值(Decaying Average)为理论基础来实现的,在垃圾收集过程中,G1收集器会记录每个Region的回收耗时、每个Region记忆集里的脏卡数量等各个可测量的步骤花费的成本,并分析得出平均值、标准偏差、置信度等统计信息。这里强调的“衰减平均值”是指它会比普通的平均值更容易受到新数据的影响,平均值代表整体平均状态,但衰减平均值更准确地代表“最近的”平均状态。换句话说,Region的统计状态越新越能决定其回收的价值。然后通过这些信息预测现在开始回收的话,由哪些Region组成回收集才可以在不超过期望停顿时间的约束下获得最高的收益。

相关文章:

JVM面试(七)G1垃圾收集器剖析

概述 上一章我们说了,G1收集器,它属于里程碑式的发展,开创了面向局部收集垃圾的概念。专门针对多核处理器以及大内存的机器。在JDK9中,更是呗指定为官方的GC收集器。满足高吞吐的通知满足GC的STW停顿时间尽可能的短。 虽然现在我…...

php转职golang第一期

入局golang 基础语法:学习 Go 语言的基本语法、数据类型、流程控制等。 数据结构与算法:掌握常用的数据结构和算法。 Web 开发基础:了解 HTTP 协议、Web 开发的基本概念。 Gin 框架或其他 Web 框架:深入学习使用一种 Go 的 Web…...

java后端服务监控与告警:Prometheus与Grafana集成

Java后端服务监控与告警:Prometheus与Grafana集成 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在现代的微服务架构中,监控和告警是确保服务稳定性的关键组成部分。Pr…...

【系统架构设计师】工厂方法设计模式

工厂方法(Factory Method)模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定要实例化的类是哪一个。工厂方法让类的实例化延迟到子类中进行。 工厂方法模式的主要角色 产品(Product):定义工厂的创建对象的接口。具体产品(Concrete Product):实…...

怎样解决OpenEuler下载sdl2失败

OpenEuler 下载 sdl2失败 解决办法(使用wget中git上下载) wget https://github.com/libsdl-org/SDL/releases/download/release-2.30.6/SDL2-2.30.6.tar.gz使用yum下载,下载的最后说找不到这样的库(no match)使用 apt-get,说找不到apt-get使用curl冲gi…...

基于Python的自然语言处理系列(2):Word2Vec(负采样)

在本系列的第二篇文章中,我们将继续探讨Word2Vec模型,这次重点介绍负采样(Negative Sampling)技术。负采样是一种优化Skip-gram模型训练效率的技术,它能在大规模语料库中显著减少计算复杂度。接下来,我们将…...

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五…...

大数据之Flink(六)

17、Flink CEP 17.1、概念 17.1.1、CEP CEP是“复杂事件处理(Complex Event Processing)”的缩写;而 Flink CEP,就是 Flink 实现的一个用于复杂事件处理的库(library)。 总结起来,复杂事件处…...

设计模式学习[5]---装饰模式

文章目录 前言1. 原理阐述2. 举例2.1 人装饰方案一2.2 人装饰方案二2.3 人装饰方案三 总结 前言 近期在给一个已有的功能拓展新功能时,基于原有的设计类图进行讨论。其中涉及到了装饰模式,因为书本很早已经看过一遍,所以谈及到这个名词的时候…...

3.C_数据结构_栈

概述 什么是栈: 栈又称堆栈,是限定在一段进行插入和删除操作的线性表。具有后进先出(LIFO)的特点。 相关名词: 栈顶:允许操作的一端栈底:不允许操作的一端空栈:没有元素的栈 栈的作用: 可…...

Debian11安装DolphinScheduler

安装地址 前置准备工作 JDK安装 下载JDK (1.8),安装并配置 JAVA_HOME 环境变量,并将其下的 bin 目录追加到 PATH 环境变量中。如果你的环境中已存在,可以跳过这步 二进制包安装DolphinScheduler 依赖 apt-get install psmisc 二进制安…...

C语言深度剖析--不定期更新的第五弹

const关键字 来看一段代码&#xff1a; #include <stdio.h> int main() {int a 10;a 20;printf("%d\n", a);return 0; }运行结果如下&#xff1a; 接下来我们在上面的代码做小小的修改&#xff1a; #include <stdio.h> int main() {const int a 1…...

python之事务

事务&#xff08;Transaction&#xff09;是数据库管理系统&#xff08;DBMS&#xff09;中的一个重要概念&#xff0c;用于确保一组数据库操作要么全部成功&#xff0c;要么全部失败&#xff0c;从而保证数据的一致性和完整性。 事务ACID 特性 事务具有以下四个特性&#xf…...

文件加密软件都有哪些?推荐6款文件加密工具

不久前&#xff0c;一家知名科技公司的内部文件在未经授权的情况下被泄露到了网络上&#xff0c;其中包括了公司的核心技术蓝图、客户名单及未来战略规划。这一事件不仅给公司带来了巨大的经济损失&#xff0c;还严重损害了企业的声誉。 如何防止以上事件的发生呢&#xff0c;文…...

Docker中的容器内部无法使用vi命令怎么办?

不知道你是否遇到过,在修改容器内部的配置的时候,有时候会提示vi命令不可用。尝试去安装vi插件,好像也不是很容易,有什么办法可以帮助我们修改这个配置文件呢? 解决办法 这时候,我们就需要用到docker cp 命令了,它可以帮助我们把容器内部的文件复制到宿主机上,也可以将…...

【Linux系统编程】TCP实现--socket

使用套接字socket实现服务器和客户端之间的TCP通信。 流程如下&#xff1a; 实现代码&#xff1a; /* server.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <s…...

企业微信hook协议接口,聚合群聊客户管理工具开发

服务提供了丰富的API和SDK&#xff0c;可以在企微的功能之上进行应用开发和功能扩展 自建应用可以调用企微hook或协议提供的接口来实现数据交互&#xff0c;可以直接调用hook或协议接口提供的功能来进行消息的发送与接收、用户管理、应用管理等操作&#xff0c;通过接口可以实…...

Selenium集成Sikuli基于图像识别的自动化测试

看起来您提供了一个链接,但目前我并没有从该链接获取到具体的信息内容。不过,如果您希望了解如何将Sikuli集成到Selenium中,我可以为您提供一些基本的指南。 什么是Sikuli? Sikuli是一款开源工具,用于基于图像识别的自动化测试。它可以识别屏幕上的图像,并模拟用户的交…...

【STM32实物】基于STM32设计的智能仓储管理系统(程序代码电路原理图实物图讲解视频设计文档等)——文末资料下载

基于STM32设计的智能仓储管理系统 演示视频: 基于STM32设计的智能仓储管理系统 摘要 近年来,随着我国仓储发展的和药品需求的不断增多,许多医院都采用药物仓储管理系统。我国的药物仓储产业已经有了长足的发展,仓库的规模不断变大,对仓储的要求也不断增高,药物的存储,…...

libtool 中的 .la 文件说明

libtool 中的 .la 文件说明 1 概述 在 Linux 系统中&#xff0c;libtool 是一个用于自动化编译和链接复杂软件项目的工具&#xff0c;特别是那些使用了共享库&#xff08;.so 文件在 Linux 上&#xff0c;.dylib 在 macOS 上&#xff09;的项目。它帮助处理各种编译器和链接器…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...