JVM(二十三)—— 垃圾回收器(三)G1垃圾回收器

news/2024/4/29 7:31:51/文章来源:https://blog.csdn.net/weixin_40920359/article/details/127832875

G1垃圾回收器:区域化分代式

  • G1概述
  • G1的特点(优势)
  • G1的缺点
  • G1的参数设置
  • G1的适用场景
  • 分区region:化整为零
  • 记忆集和写屏障
  • G1回收器垃圾回收过程
    • 年轻代GC
    • 并发标记过程
    • 混合回收

G1概述

应用程序所应对的业务越来越庞大,复杂,用户越来越多,没有GC就不能保证应用程序正常运行,而经常赞成STW的GC又跟不上十几的需求,所以才会不断地尝试对GC进行优化。G1(Garbage First)垃圾回收器在JDK7引入的一个新的垃圾回收器,也是在JDK9中默认垃圾收集器,是当今收集器技术发展最前沿成果之一。

同时,为了适应现在不断扩大的内存和不断增加的处理器数量,进一步降低暂停时间,同时兼顾良好的吞吐量。官方给G1设定的目标是在延迟可控的情况下获得尽可能高的吞吐量。

G1是一个并行回收器,它把堆内存风格为很多不相关的区域(region,物理上不连续)。使用不同的region来表示Eden,S0,S1,Old区域等。

G1有计划地避免在整个Java堆中进行全区域的垃圾收集,G1跟踪各个region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的region。

由于这种方式的侧重点在于回收垃圾最大量的区间,所以我们给G1一个名字:垃圾优先。

G1是一款面向服务端应用的垃圾收集器,主要针对配备多核CPU及大容量内存的机器,以极高概率满足GC停顿时间的同时,还兼具高吞吐量的性能特征。

G1的特点(优势)

G1垃圾回收思想和之前的并不一样,如下图:
在这里插入图片描述
而是将空间分成了很多小的区间(region)
在这里插入图片描述
并行与并发:

  • 并行性:G1在回收期间,可以有多个GC线程同时工作,有效利用多核计算能力。此时用户线程STW.
  • 并发性:G1拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会在整个回收阶段完全阻塞应用程序的情况。

分代收集:

  • 从分代上看,G1依然属于分代型垃圾回收器,它会区分年轻代和老年代,年轻代依然有Eden区和幸存者区。但从堆的结构上看,他不要求整个Eden区,年轻代或者老年代都是连续的,也不再坚持固定大小和固定数量。
  • 将堆空间分为若干个区域(region),这些去榆中包含了逻辑上的年轻代和老年代。
  • 和之前的各类回收器不同,它同时兼顾年轻代和老年代,对比其他回收器,或者工作在年轻代,或者工作在老年代。

空间整合

  • G1将内存会分为一个个的region。内存的回收是以region作为基本单位的。region之间是复制算法,但整体上实际可以看作是标记压缩算法,两种算法都可以避免内存碎片。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。尤其是当Java堆非常大的时候,G1的优势更加明显。

可预测的停顿时间模型
这是G1相对CMS的另一大优势,G1除乐追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不超过N毫秒。

  • 由于分区的原因,G1可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局挺短的发生也能得到较好的控制。
  • G1跟踪各个region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的region。保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。
  • 相比CMS,G1未必能做到CMS在最好情况下的延时停顿,但是最差情况要好很多。

G1的缺点

相较于CMS,G1还不具备全方位,压倒性优势。在用户程序运行过程中,G1无论是为了垃圾收集产生的内存占用还是程序运行时的额外执行负载都要比CMS要高。

从经验上来说,在小内存应用上CMS的表现大概率会优于G1,而G1在大内存应用商店则发挥其优势。平衡点在6-8G之间。

G1的参数设置

在这里插入图片描述

G1的适用场景

在这里插入图片描述

分区region:化整为零

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

虽然还保留新生代和老年代的概念,但是新生代和老年代不再是物理隔离的了,他们都是一部分region的集合。通过region的动态分配方式实现逻辑上的连续。

在这里插入图片描述

一个region有可能属于Eden,幸存者,或者老年代内存区域。但是一个region只可能属于一个角色,图中E表示该region属于Eden内存区域,S表示属于幸存者内存区域,O表示属于Old区域。空白表示未使用的内存空间。

G1垃圾收集器还增加了一种新的内存区域,叫做humongous内存区域,如图中H块。主要用于存储大对象,如果超过1.5个region,就放在H。

对于堆中的大对象,默认直接会被分配到老年代,但是如果它是一个短期存在的大对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个humongous区,它用来专门存大对象。如果一个H区装不下一个大对象,那么G1会寻找连续的H区来存储。为了能找到连续H区,有时候不得不启动Full GC,G1的大多数行为都把H区作为老年代的一部分来看待。

记忆集和写屏障

在这里插入图片描述
我们应该清楚,一个region不可能试试孤立的,一个region中的对象可能被其他任意region的对象引用,判断对象存活时,是否需要扫描整个Java堆才能保证准确? 这样就会出现回收新生代时也不得不同时扫描老年代,如果这样就会降低新生代GC的效率。

无论G1还是其他分代收集器,JVM都是使用记忆集来避免全局扫描的:
每个region都有一个对应的记忆集,每次引用类型数据写操作时,都会产生一个写屏障暂时中断操作。然后检查将要写入的引用指向的对象是否和该引用类型数据在不同的region(其他收集器检查老年代对象是否引用了新生代对象)。如果不同,通过卡表吧相关引用信息记录到引用指向对象所在的region对应的记忆集中。当进行垃圾收集时,在GC根节点枚举范围假如记忆集,就可以保证不进行全局扫描,也不会有遗漏。

G1回收器垃圾回收过程

G1回收过程包括以下环节:

  • 年轻代GC
  • 来年代并发标记过程
  • 混合回收
  • 如果需要,单线程,独占式,高强度Full GC还是继续存在的。它针对GC的评估失败提供了一种失败保护机制,即强力回收。
    在这里插入图片描述
    应用程序分配内存,当年清代的Eden区用尽时开始年轻代回收过程;G1的年轻代手机阶段是一个并行的独占式收集器。在年轻代回收期,G1暂停所有应用线程,启动多线程执行年轻代回收。然后从年轻代区间移动存活对象到幸存者区或者老年区,也有可能是两个区间都会涉及。

当堆内存使用达到一定值(默认45%),开始老年代并发标记过程。

标记完成马上开始混合回收过程。对于一个混合回收期,G1从老年区间移动存活对象到空闲区间,这些空闲区间也就成为了老年代的一部分,和年轻代不同,老年代的G1回收器和其他GC不同,G1的老年代回收器不需要整个老年代回收,一次只需要扫描部分老年代的region就可以了,同时这个老年代region和年轻代一起被回收的。

年轻代GC

JVM启动时,G1先准备好伊甸园区,程序在运行过程中不断创建对象到伊甸园区,当伊甸园区空间耗尽时,G1会启动一次年轻代垃圾回收过程。
年轻代GC时,首先G1停止应用程序的执行(STW),G1创建回收集,回收集是指需要被回收的内存分段的集合,年轻代回收过程的回收集包含伊甸园区和幸存者区所有的内存分段。

在这里插入图片描述
然后开始如下回收过程:

第一阶段:扫描根
根是指static变量指向的对象,正在执行的方法调用链条上的局部变量等。根引用连同记忆集记录的外部引用作为扫描存活对象的入口。
第二阶段:更新记忆集
处理dirty card queue 中的card,更新记忆集。此阶段完成后,记忆集可以准确的反应老年代对所咋的内存分段中对象的引用。
第三阶段:处理记忆集
识别被老年代对象指向的伊甸园中的对象,这些被指向的伊甸园中的对象被认为是存活的对象。
第四阶段:复制对象
此阶段,对象数被遍历,伊甸园区内存段中存活的对象会被复制到幸存者区中空的内存段,幸存者区内存段中存活的对象如果年龄没有达到阈值,年龄会+1,达到阈值会被复制到养老区中空的内存段。如果幸存者空间不够,伊甸园空间的部分数据会直接晋升到老年代空间。
第五阶段:处理引用
处理强软弱虚等引用,最终伊甸园空间的数据为空,GC停止工作,而目标内存中的对象都是联系存储的,没有碎片,所以复制过程可以达到内存整理的效果,减少碎片。

并发标记过程

初始化阶段
标记从根节点直接可达对象,这个阶段是STW的,并且会触发一次年轻代GC.
根区域扫描
G1 扫描幸存者区直接可达的老年代区域对象,并标记被引用的对象,这一过程必须在年轻代GC之前完成。
并发标记
在整个堆中进行并发标记(和应用程序并发执行),此过程可能被年轻代GC中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那这个区域会被立即回收。同时,并发标记过程中,会计算每个区域的对象活性(去榆中存活对象的比例)。
在此标记
由于应用程序进行,需要修正上一次的标记结果。是STW的。G1中采用了比CMS更快的初始快照算法。
独占清理
计算各个区域的存活对象和GC回收比例。并进行排序,识别可以混合回收的区域,为下阶段做铺垫,是STW的,这个阶段并不会实际上去做垃圾的收集。
并发清理阶段
识别并清理完全空闲的区域。

混合回收

在这里插入图片描述
当越来越多的对象晋升到老年大old region时,为了避免堆内存耗尽,虚拟机会触发一个混合的垃圾收集器,该算法并不是一个Old GC,除了回收整个年轻region,还会回收一部分old region。
在这里插入图片描述

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

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

相关文章

【大数据】flink 读取文件数据写入ElasticSearch

前言 es是大数据存储的必备中间件之一,通过flink可以读取来自日志文件,kafka等外部数据源的数据,然后写入到es中,本篇将通过实例演示下完整的操作过程; 一、前置准备 1、提前搭建并开启es服务(本文使用doc…

图像分割 - Hough变换直线检测

目录 1. Hough 直线检测 2. HoughLinesP 函数 1. Hough 直线检测 霍夫变换(Hough 变换):利用对偶原理,把原空间的问题转换到对偶空间去求解 这里涉及到空间转换,将原来的笛卡尔空间(xy空间)…

App安全架构之前端安全防护

近年来,随着互联网、物联网、移动设备、5G通讯等技术的齐头发展,人类的生活和工作越来越离不开软件和互联网,正如人类社会文明发展到一定程度以后,会需要法律等社会规范来保护一样,线上环境也是一样道理。 Gartner 对…

Python学习小组课程-课程大纲与Python开发环境安装

一、前言 注意:此为内部小组学习资料,非售卖品,仅供学习参考。 为提升项目落地的逻辑思维能力,以及通过自我创造工具来提升工作效率,特成立Python学习小组。计划每周花一个小时进行在线会议直播学习,面向…

国内访问Github超级慢?那是你没有用我这个脚本。直接起飞。

导语 之前很多朋友咨询过国内访问Github较慢的问题,然后我一般让他们自己去知乎上找攻略,但今天我才发现网上竟然没有一个一键配置的脚本,一般都需要我们跟着教程一步步地去做才行。这也太麻烦了,于是自己动手写了个脚本&#xf…

ceph浅谈

总谈 ceph简介 用上ceph,多台机器的磁盘空间在一起了,在一台机器上就可以看到使用所有空间。 还可以保存多份安全备份 存储先ceph,自我管理修复,跨机房,节点越多,并行化,论上,节点越…

1-(3-磺酸基)丙基-1-甲基-2-吡咯烷酮三氟甲磺酸盐[C3SO3Hnmp]CF3SO3

1-(3-磺酸基)丙基-1-甲基-2-吡咯烷酮三氟甲磺酸盐[C3SO3Hnmp]CF3SO3 离子液体(IonicLiquids)是完全由离子组成,现在多指在低于100摄氏度时呈液体状态的熔盐。通常由特定的有机阳离子和无机阴离子(或有机阴离子)构成。 离子液体特点 蒸汽压…

C++基础——模板讲解

目录 一. 泛型编程 二. 函数模板 1.格式: 2.定义: 1.隐式实例化 2.显式实例化 3.解决方法3:使用多个T类型 4.在C中编译器允许非模板函数和模板函数同时存在 一. 泛型编程 先来看一段代码: void Swap(int& p1, int&am…

LeetCode:8. 字符串转换整数 (atoi)

8. 字符串转换整数 (atoi)1)题目2)思路3)代码4)结果1)题目 请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C 中的 atoi 函数…

逻辑判断与正则表达式文本处理

上一篇文章分享了正则表达式的操作,这一篇文章就让我们一起看看正则表达式与逻辑判断结合起来会发生什么吧!感兴趣的小伙伴欢迎评论区或者是私信留言! 一、题目描述: 输入一个字符串,检查其是否为合法的python变量。输入$$$结束:…

数据结构【队列】

文章目录(一)队列定义(二)队列实现(1)创建结构体(2)具体函数实现及解析1.1 初始化队列1.2入队列1.3出队列1.4取队首元素1.5取队尾元素1.6返回队列个数1.7判断是否为空1.8销毁队列&am…

FITC标记的STAT1-ASON,绿色荧光素标记STAT1反义寡核苷酸,FITC-STAT1-ASON

产品名称:FITC标记的STAT1-ASON,绿色荧光素标记STAT1反义寡核苷酸 ​​​​​​​英文名称:FITC-STAT1-ASON STAT1 是第一个被发现的 STATs 家族成员,其编码基因位于 2 号染色体上,由 750 个氨基酸残基组成&#xff…

随想录一刷Day55——动态规划

文章目录Day55_动态规划47. 判断子序列48. 不同的子序列Day55_动态规划 47. 判断子序列 392. 判断子序列 思路: 双指针很简单,O(n)O(n)O(n) 时间就能解决 这里还是用dp dp[i][j] 表示以 s[i - 1] 结尾的字符串和以 t[]i-1 为结尾的字符串的最大子序列长…

Linux篇【5】:Linux 进程概念(二)

目录 3.5、查看进程 3.6、通过系统调用接口获取正在进行的进程的标识符 3.7、通过系统调用接口创建子进程 - fork 初识 3.5、查看进程 [HJMhjmlcc ~]$ clear [HJMhjmlcc ~]$ pwd /home/HJM [HJMhjmlcc ~]$ ls [HJMhjmlcc ~]$ touch mytest.c [HJMhjmlcc ~]$ ls mytest.c [H…

基于51单片机的简易数字计算器Proteus仿真

资料编号:115 下面是相关功能视频演示: 115-基于51单片机的简易数字计算器Proteus仿真(源码仿真全套资料)功能说明: 该计算器系统51 系列的单片机进行的数字计算器系统设计,可以完成计算器的键盘输入&…

一看就会的Java方法

文章目录一、方法的定义和使用🍑1、为什么引入方法?🍑2、方法的定义🍑3、方法调用的执行过程🍑4、实参和形参的关系二、方法重载🍑1、为什么需要方法重载🍑2、方法重载的概念和特点&#x1f351…

用DIV+CSS技术设计的体育主题网站(足球介绍)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

【面经】之小鼠喝药问题

题目 现在有 10 只小白鼠和 1000 支药水,1000 支药水中有且仅有一支药水有毒,如果小白鼠喝下毒药,那么毒发的时间是两小时。 现在只给你两小时的时间,请问如何用这 10 只小白鼠测出哪支药水有毒?(忽略小白…

linux系统文件权限

目录 shell命令以及运行原理 具体体现(命令行解释器) Linux权限的概念 Linux下有两种用户:超级用户(root)、普通用户 su指令 Linux权限管理方面 文件访问者的分类(人) 为什么要有所属组? 文件属性…

STM32 Bootloader开发记录 2

在《stm32 bootloader开发记录.md》文档中,已经实现了Bootloader下的升级功能。可以在Bootloader启动时,进入升级模式,使用串口传输数据,来下载固件到flash中。 但是,在实际应用中,一般是在应用运行过程中…