G1收集器简介

        G1是一款既收集新生代又收集老年代的收集器,使用它可以实现整个java堆的gc,它有两个非常重要的新概念:region和remember set(简称rset)。

        region是啥?

        G1中虽然保留了新生代和老年代的概念,但是不像其他收集器那样使用物理内存隔离来区分新生代和老年代,在G1中新生代和老年代实现的是逻辑上的内存隔离,G1将整个的java堆最多分成2048个大小相等的region,每个region的大小为整堆实际大小/2048,在1-32M之间,并且为2的N次幂。对象是存储在region中的,有四种不同类型的region:E、S、O、H,分别对应着eden区的region、survivor区的region、老年代的region和h区的region,eden区的region用于存储新被创建的非巨型对象,survivor区的region用于存储从eden区复制过来的年龄还未达到15的存活对象,老年代的region用于存储从新生代晋升过来的老化对象,这些对象大多都是经过了多次gc仍然存活的对象,对象的存活概率非常大,h区用于存储巨型对象,那么什么是巨型对象呢?巨型对象是指体积庞大需要占用内存比较大的对象,在G1中对于巨型对象的定义是体积超过了一个region的容量的50%以上的对象。在其他的收集器实现中,巨型对象在被创建之后直接存放在老年代,在G1中,巨型对象在被创建之后是存放在h区的region中的,一个巨型对象会占用一个或多个连续的h区region。因为在G1中新生代和老年代实现的是逻辑内存的隔离,所以G1也不要求相同类型的region必须相邻。在G1中对象被保存在region中,所以在gc的时候,也是对region中的对象执行可达性分析,在可达性分析过程中,用到了一个新的概念:rset,G1收集器会用gc roots对象配合着rset记录来实现对象的可达性分析,那么什么是rset呢?

        rset是啥?

        rset是在G1收集器中使用的一个新的数据结构,它是一个列表,G1收集器会为每一个region创建一个rset,rset中记录的是其他老年代region中的对象对于此region中对象的引用,为啥要记录这些引用呢?我们知道,在其他的收集器中,当去执行对象的可达性分析时,需要沿着gc roots对象的引用链去查找对象,根据引用关系判断对象是否可达,而这些引用关系需要通过整堆扫描的方式才能获得,可整堆扫描耗时太长,为了在这一块儿进行优化,G1引入了rset去将引用关系记录下来,这样在可达性分析阶段就可以用扫描rset来代替整堆扫描了,大大提高了收集性能。

        G1的收集模式是怎样的呢?

        G1支持两种收集模式:young gc和mixed gc(混合收集)。young gc是对于新生代region的gc,混合gc是对于所有新生代region和部分老年代region的gc。

        什么时候触发young gc呢?young gc并非是一遇到eden内存不足以存储新对象就立即触发的,初次遇到eden区的region不足以存储新对象时,G1首先做的是为eden区分配新的region,因为此时新生代的region占比仅为整堆内存的5%,G1允许继续为eden区分配新的region,但是新生代占比不能超过60%,当占比接近60%时,eden区的region内存不足就会触发young gc了。young gc在执行的时候,会利用gc roots对象和rset记录对新生代的region中的对象执行可达性分析,并且将存活对象拷贝到空闲的s区region中去,当然在这个过程中要完成存活对象年龄的增长,如果有哪个对象的年龄达到了15,那这个对象会被晋升到老年代的region中存储,如果eden区的region中有大量的对象存活了下来而没有足够的s区region去存储它们,也会有部分对象被直接存储到老年代region中。存活对象复制完毕后,将eden区的region以及只包含着垃圾的那些s区region清空。

        随着程序的执行,不断有对象从新生代晋升到老年代中,老年代的region也慢慢被对象堆积起来,当老年代region占用达到了设置的整堆比阈值(默认45%)时,就要触发混合gc了,混合gc是对于全部的新生代region以及部分老年代region的收集,为什么是部分老年代而不是全部老年代呢?这是因为G1收集器另外一个新特性:支持可预测的STW时间设置,G1收集器支持我们设置在m毫秒时长内可用于STW的最大时长n的值,G1收集器需要在我们限定的这个时长内完成gc,所以它不能收集全部的region,只能收集部分region,那么收集哪一部分region呢?G1会对老年代所有region中的对象执行可达性分析,分析完成之后,所有region中的垃圾堆积情况就确定了,然后会对这些region按照回收价值和回收成本做一个优先级排序,有着更高的回收价值和更低的回收成本的region总会具有更高的优先级,而混合gc中被收集的也是具有最高优先级的那一部分region。

        G1收集器同CMS收集器一样,也追求更短的STW时间,所以它也是并发收集器的实现,它的收集过程也分为四个步骤:

        1、初始标记:初始标记是去标记gc roots对象以及被gc roots对象直接关联的对象,这个过程要暂停用户线程,会有短暂的STW时间;

        2、并发标记:并发标记是根据gc roots对象以及rset记录去标记其他对象,这个过程gc线程与用户线程并发,虽然耗时较长,但是用户线程不用暂停,没有STW时间;

        3、重新/最终标记:因并发标记这一步,用户线程保持执行,那么难免在执行中发生对象引用关系的变化而造成多标和漏标的问题,因为漏标导致的结果很严重,会让不该被回收的对象被gc回收掉而造成程序错误,所以需要有重新标记过程。在并发标记过程中,如果有个白色对象被新引用了,这个引用会被记录下来,在重新标记阶段去为它标记颜色;即:重新标记是为了做标记修正。这一步需要暂停用户线程,会有STW时间,但是这一步耗时非常短;

        4、筛选回收:按照优先级筛选部分region进行回收,这一步虽然会暂停用户线程,但是会有多个gc线程并行回收,STW时间很短。

        G1收集器的优点:

        1、并行与并发:G1收集器充分利用多核CPU的优势,让用户线程与gc线程并发,缩短了STW时间,实现了更高的性能;

        2、分代收集:G1收集器保留了分代的概念,既可以收集新生代,又可以收集老年代,无需其他收集器配合就能管理整个的java堆;

        3、没有内存碎片问题:G1收集器从局部看用的是复制算法,从整体看用的是标记-整理算法,没有CMS收集器的内存碎片问题;

        4、可预测的STW时间:G1收集器支持可预测的STW时间模型设置,让我们可以实现更好的用户线程暂停管理。

        

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

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

相关文章

Spring Boot程序输出远程访问IP

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《SpringBoot开发》。🎯🎯…

03 HAL库下UART的使用

引言: 需要使用到的uart调试工具在文章最后的资料里面 题外话:uart和usart的区别 UART(Universal Asynchronous Receiver/Transmitter)和USART(Universal Synchronous/Asynchronous Receiver/Transmitter)…

获取Windows10系统原始安装日期

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 目标 获取Windows10系统最原始的安装日期;例如:刚买电脑时安装系统的时间。 步骤 第一步,请打开PowerShell,单击Windows P…

评价类问题:层次分析法

引言:打分法 一、解决评价类问题的三个方面 二、如何寻找评价准则 三、如何确定权重 (1)分而治之的思想 (2) 层次分析法思想: 指标重要性(满意程度) 判断矩阵(正反矩…

面试题-JVM 初级面试题(40道含答案)

author: 小郑说编程 JVM 初级面试题 1、对象在哪块内存分配? 数组和对象在堆内存分配;某些对象没有逃逸出方法,可能被优化为在栈上分配 2、谈谈 JVM 中的常量池 JDK 1.8 开始 字符串常量池:存放在堆中,包括 Strin…

分布式【4. 什么是 CAP?】

什么是 CAP? C 代表 Consistency,一致性,是指所有节点在同一时刻的数据是相同的,即更新操作执行结束并响应用户完成后,所有节点存储的数据会保持相同。 A 代表 Availability,可用性,是指系统提…

[原创][R语言]股票分析实战[6]:正则表达式提取子字符串

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…

LeetCode75| 滑动窗口

目录 643 子数组最大平均数 | 1456 定长子串中元音的最大数目 1004 最大连续1的个数 ||| 1493 删掉一个元素以后全为1的最长子数组 643 子数组最大平均数 | class Solution { public:double findMaxAverage(vector<int>& nums, int k) {double sum 0;double re…

数据结构与算法笔记

数据结构&#xff1a; 就是指一组数据的存储结构 算法&#xff1a; 就是操作数据的一组方法 数据结构和算法 两者关系 数据结构和算法是相辅相成的。数据结构是为算法服务的&#xff0c;算法要作用在特定的数据结构之上。 数据结构是静态的&#xff0c;它只是组织数据的一…

Quartz调度引擎基于MySQL的高可用架构调度延迟分析与解决方案

1、Quartz默认使用的高可用架构 在Quartz的官方文档中&#xff0c;介绍了一种默认的高可用架构&#xff0c;基于数据库实现。该方案中&#xff0c;多台Quartz服务器连接同一个数据库&#xff0c;单台服务器每次调度检索并锁定一批Trigger用于触发&#xff0c;锁定过程中将先从…

Kubernetes网络-VXLAN

一. 网络基础 1. 计算机网络的分层 如今连接方式也越来也丰富&#xff0c;网线、WiFi、蓝牙、光纤&#xff0c;甚至我们普通的电线、照明所用的灯光&#xff0c;都可以作为接入网络的介质。如此庞大的网络&#xff0c;丰富多样的设备&#xff0c;计算机网络技术能把它们统一起…

认识计算机网络——计算机网络的组成

计算机网络是由多个计算机和网络设备组成的系统&#xff0c;通过通信协议实现数据传输和信息交换。它是现代社会信息技术的重要支撑&#xff0c;广泛应用于各个领域。本文将介绍计算机网络的主要组成部分&#xff0c;包括硬件设备、软件协议和网络服务。 一、硬件设备 计算机网…

46、激活函数 - Relu 激活

本节介绍一个在神经网络中非常常见的激活函数 - Relu 激活函数。 什么是ReLU激活函数 ReLU 英文名为 Rectified Linear Unit,又称修正线性单元,是一种简单但很有效的激活函数,它的定义如下: 即当输入 x 大于零时,输出等于他自己;当输入小于等于零时,输出为零,下面是re…

【Android进阶篇】Android中PreferenceScreen的作用和详细用法介绍

1&#xff0c;PreferenceScreen的作用 在Android开发中&#xff0c;PreferenceScreen是一个非常重要的布局控件&#xff0c;主要用于创建设置界面&#xff08;settings page&#xff09;。它可以包含多个Preference子项&#xff0c;如CheckBoxPreference, ListPreference等&am…

C++继承与派生——(8)多继承

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 苦难和幸福一样&#xff0c;都是生命盛…

【多传感器融合导航论文阅读】

多传感器融合导航论文积累 知识点总结因子图一致因子图 文献阅读笔记[IF 18.6] 知识点总结 因子图 Factor Graph 是概率图的一种&#xff0c;是对函数因子分解的表示图&#xff0c;一般内含两种节点&#xff0c;变量节点和函数节点。 因子图存在着&#xff1a;两类节点&#…

主浏览器优化之路1——你现在在用的是什么浏览器?Edge?谷歌?火狐?360!?

上一世&#xff0c;我的浏览器之路 引言为什么要用两个浏览器为什么一定要放弃火狐结尾给大家一个猜数字小游戏&#xff08;测运气&#xff09; 引言 小时候&#xff0c;我一开始上网的浏览器是2345王牌浏览器吧&#xff0c; 因为上面集成了很多网站&#xff0c;我记得上面有7…

使用axios发送get和post请求

使用axios发送get和post请求的方法如下&#xff1a; 1.发送GET请求&#xff1a; axios.get(url).then(response > {// 请求成功的处理逻辑console.log(response.data);}).catch(error > {// 请求失败的处理逻辑console.error(error);});2.发送POST请求&#xff1a; ax…

Loading 加载 Taro + vue3 自定义组件的封装和 分页 优化

1.需求 当需要实现一个组件 上拉加载的组件 我们可以选择某些组件库的组件。 但是有的组件没有这个组件&#xff0c;比如跟Taro 框架配套的京东nut-ui组件库 没有提供这个功能, 2.Loading组件 ①封装 <template><div class"container"><div class&…

原型继承在 JavaScript 中是如何工作

原型继承是 JavaScript 中实现面向对象编程的一种机制。在 JavaScript 中&#xff0c;每个对象都有一个原型&#xff0c;原型是一个对象&#xff0c;它包含了对象的属性和方法。当我们试图访问一个对象的属性或方法时&#xff0c;JavaScript 先在对象本身中查找&#xff0c;如果…