G1垃圾收集器

1.G1的目的:

Garbage First,也就是垃圾优先原则,也就是空间方面的关注点。同时照顾到停顿时间以及吞吐量。

G1垃圾收集器的设计目的是避免完全回收,但是当并发收集不能足够快地回收内存时,就会发生完全回收GC。G1的完整GC的当前实现使用单线程mark-sweep compact算法。

1.1JDK8为什么不用CMS做为默认垃圾收集器呢

1.CMS单线程或者双线程情况下效率很低

2.CMS会并发失败

3.CMS可中止的预处理会导致极限5S停顿

4.并发失败进入foregroud还会导致进入Full GC,全局MSC整理

5.CMS吞吐的设计并不是很优秀

1.2G1的特点:

内存空间的重新定义

更短的停顿时间,要多短就多短

某种程度上去解决空间碎片

2.内存空间的重新定义:region  

G1的一个Region大小可以单独设定,可以1-32M,设置需要已2的n次幂来设置,因为很多算法都是已2的n次幂来计算的,所以Region大小也要按照这个来实现

G1虽然保留了新老年代的概念,但是G1把他们分成了一个一个的Region。

2.1Region的角色:

自由角色FreeTag

新生代分区 YoungHeapRegion,细分为eden分区和survivor分区

大对象分区 HHR,细分为大对象头分区和大对象连续分区

老年代分区 OHR

JDK11之后有一类特殊的分区,叫做归档分区,关闭归档分区以及开放归档分区

3.TLAB(线程本地分配缓冲区 Thread Local Allocation Buffer)

分配空间时,为了提高JVM的运行效率,应当尽量减少临界区范围,避免全局锁。G1的通常的应用场景中,会存在大量的访问器同时执行,为减少锁冲突,JVM引入了TLAB(线程本地分配缓冲区 Thread Local Allocation Buffer)机制。

3.1TLAB作用:

我们知道对象内存分配时最初考虑在新生代的Eden区为对象分配内存,但堆区是线程共享的区域,在多线程环境下多个线程同时操控同一块内存的现象是普遍的,为了保证对象分配时数据的安全性,我们需要用全局锁来解决多线程同时访问同一块内存的问题,但全局锁会降低效率与程序的吞吐量,为了解决该问题TLAB应运而生

在分配线程对象时从JVM堆中分配一个固定大小的内存区域并将其作为线程的私有缓冲区,这个缓冲区称为TLAB只有在为每个线程分配TLAB缓冲区时才需要锁定整个JVM堆。

由于TLAB是属于线程的,不同的线程不共享TLAB,当我们尝试分配一个对象时,优先从当前线程的TLAB中分配对象,不需要锁,因此达到了快速分配的目的。

实际上TLAB是Eden区域中的一块内存,不同线程的TLAB都位于Eden区,所有的TLAB内存对所有的线程都是可见的,只不过每个线程有一个TLAB的数据结构,用于保存待分配内存区间的起始地址(start)和结束地址(end),在分配的时候只在这个区间做分配,从而达到无锁分配,快速分配。

虽然TLAB在分配对象空间的时候是无锁分配,但是TLAB空间本身在分配的时候(分配TLAB内存空间)还是需要锁的,G1中使用了CAS来并行分配。
 

对象的分配实在TLAB中进行,由于每个线程都有一个独立的TLAB,所以可以达到无锁分配,如果失败了就会发生GC

3.2G1对新老年代中的相互引用是怎么处理的?

G1在进行oldGC的时候都会进行youngGC,所以不用管新生代指向老年代的问题

记录引用关系的2中方式

obj1=obj2

out:所有的引用关系都记录在obj1中,我引用了谁

in:所有的引用关系都记录在obj2,谁引用了我,G1使用的这种,但是如果位置不够怎么办,引用集

4.RSet(RemeberSet)引用集

4.1稀疏表

本质上就是一种Hash表,Key是Region的起始地址,Value是一个数组,里面存储的元素是卡页的索引号。将一个Region分成小块,每个小块都是V中的一个值

4.2粗粒度位图

当细粒度位图 size超过阈值时,所有region 形成一个 bitMap。如果有region 对当前 Region 有指针指向,就设置其对应的bit 为1,也就是粗粒度位图

一个位图对应一个Region

4.3细粒度位图

就是一个C位图,但是这个位图,可以详细的记录我们的内存变化,包括并发标记修改,对应元素标识等 当稀疏表指定region的card数量超过阈值时,则在细粒度位图中创建一个对应的PerRegionTable对象。一个Region地址链表,维护当前Region中所有card对应的一个BitMap集合。

5.什么是写屏障:

因为Store Buffer导致读写的顺序不一致,而写屏障可以解决这个问题 

多核情况下,cpu0与CPU1共享一个数据,如果0修改了数据那么就要将这个数据置为失效,并且通知1,还要等到1的回执才能继续执行,这样就会很慢,这时就加入了Store Buffer,先写入Store Buffer,等到收到AcKnowledgement的时候,再把数据刷入缓存,但是这个时候还有一个问题,写数据走了Store Buffer,如果读取的时候不走Store Buffer直接走cache,不就导致数据不一致了么,所以,读要同时走cache和Store Buffer

StoreBuffer,导致读写不一致

a的值可能因为是Share(共享)先被写入了Store Buffer,并发送通知其他cpu置为Invalid(失效)
b的值,可能因为在cache中已经存在并且是Exclusive(独占)直接被写进cache中。
读取的时候因为先读b的值,b被刷进主存供读取
后面要读a,因为还没收到失效通知,从cache中直接拿到a,断言失败。
 

5.1写屏障的内存伪共享问题:

如果不同线程对对象引用的更新操作,恰好位于同一个64KB区域内,这将导致同时更新卡表的同一个缓存行,从而造成缓存行的写回、无效化或者同步操作,间接影响程序性能。 

5.2解决方案:

不采用无条件的写屏障,而是先检查卡表标记,只有当该卡表项未被标记过才将其标记为dirty。 这就是JDK 7中引入的解决方法,引入了一个新的JVM参数-XX:+UseCondCardMark,

6.G1的Rset同步异步问题:

异步更新操作需要引入DCQS(Dirty Card Queue Set)结构。

JVM声明了一个全局的静态结构G1BarrierSet,其中包含两个Queue Set,DirtyCardQueueSet和G1SATBMarkQueueSet,分别用于处理DCQS和STAB

G1常用参数: -XX: +UseG1GC 开启G1垃圾收集器 -XX: G1HeapReginSize 设置每个Region的大小,是2的幂次,1MB-32MB之间 -XX:MaxGCPauseMillis 最大停顿时间 -XX:ParallelGCThread 并行GC工作的线程数 -XX:ConcGCThreads 并发标记的线程数 -XX:InitiatingHeapOcccupancyPercent 默认45%,代表GC堆占用达到多少的时候开始垃圾收集

7.G1常用参数:

-XX: +UseG1GC 开启G1垃圾收集器

-XX: G1HeapReginSize 设置每个Region的大小,是2的幂次,1MB-32MB之间

-XX:MaxGCPauseMillis 最大停顿时间

-XX:ParallelGCThread 并行GC工作的线程数

-XX:ConcGCThreads 并发标记的线程数

-XX:InitiatingHeapOcccupancyPercent 默认45%,代表GC堆占用达到多少的时候开始垃圾收集

7.G1相对于CMS的的优势:

1.G1在压缩空间方面有优势。

2.G1通过将内存空间分成区域(Region)的方式避免内存碎片问题

3.Eden、Survivor、Old区不再固定,在内存使用率上来说更灵活

4.G1可以通过设置预期停顿时间(Pause Time)来控制垃圾收集时间,避免应用雪崩现象

5.G1在回收内存后会马上同时做合并空闲内存的工作,而CMS默认是在STW(stop the world)的时候做

6.G1会在Young GC中使用,而CMS只能在Old区使用

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

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

相关文章

学习视频剪辑方法:AI智剪助力,批量处理短视频无忧

随着短视频的兴起,越来越多的人开始关注如何有效地制作和发布这些内容。但是,短视频的制作并不容易,要耗费大量的时间和精力。现在有很多AI智能剪辑工具可以快速、高效地制作短视频。其中,AI智剪是一款非常受欢迎的视频剪辑功能&a…

关于python 语音转字幕,字幕转语音大杂烩

文字转语音 Python语音合成之第三方库gTTs/pyttsx3/speech横评(内附使用方法)_python_脚本之家 代码示例 from gtts import gTTStts gTTS(你好你在哪儿!,langzh-CN)tts.save(hello.mp3)import pyttsx3engine pyttsx3.init() #创建对象"""语速"…

12V降3.3V100mA稳压芯片WT7133

12V降3.3V100mA稳压芯片WT7133 WT71XX系列是一款采用CMOS工艺实现的三端高输入电压、低压差、小输出电流电压稳压器。 它的输出电流可达到100mA,输入电压可达到18V。其固定输出电压的范围是2.5V~8.0V,用户 也可通过外围应用电路来实现可变电压…

Element中el-table组件右侧空白隐藏-滚动条

开发情况&#xff1a; 固定table高度时&#xff0c;出现滚动条&#xff0c;我们希望隐藏滚动条&#xff0c;或修改滚动条样式&#xff0c;出现table右边出现15px 的固定留白。 代码示例 <el-table class"controlTable" header-row-class-name"controlHead…

css中flex两列布局(一列自适应其他固定)

问题 最近写一个布局的时候&#xff0c;遇到一个问题。如下图的布局。在没有图片的时候布局是正常的&#xff0c;如果有图片且设置了width:100%;height: 100%; 则会出现图片将自适应布局撑开的情况。 我的解决方式是让图片不缩放&#xff0c;图片外层再添加一个div元素。形如…

如何预防数据泄露?六步策略帮您打造企业信息安全壁垒

大家好&#xff01;我是恒小驰&#xff0c;今天我想和大家聊聊一个非常重要的话题——如何预防数据泄露。在这个数字化的时代&#xff0c;数据已经成为了我们生活中不可或缺的一部分。然而&#xff0c;随着数据的价值日益凸显&#xff0c;数据泄露的风险也随之增加。企业应该如…

2023年金融信创行业研究报告

第一章 行业概况 1.1 定义 金融信创是指在金融行业中应用的信息技术&#xff0c;特别是那些涉及到金融IT基础设施、基础软件、应用软件和信息安全等方面的技术和产品。这一概念源于更广泛的“信创 (信息技术应用创新)”&#xff0c;即通过中国国产信息技术替换海外信息技术&a…

基于springboot实现农机电招平台系统项目【项目源码+论文说明】

基于springboot实现农机电招平台系统演示 摘要 随着农机电招行业的不断发展&#xff0c;农机电招在现实生活中的使用和普及&#xff0c;农机电招行业成为近年内出现的一个新行业&#xff0c;并且能够成为大群众广为认可和接受的行为和选择。设计农机电招平台的目的就是借助计算…

Mac下载的软件显示文件已损坏,如何解决文件已损坏问题,让文件可以正常运行

Mac下载的软件显示文件已损坏&#xff0c;如何解决文件已损坏问题&#xff0c;让文件可以正常运行 设备/引擎&#xff1a;Mac&#xff08;11.6&#xff09;/Mac Mini 开发工具&#xff1a;终端 开发需求&#xff1a;让显示已损坏的文件顺利安装到电脑 大家肯定都遇到过下载…

AIOps探索 | 应急处置中排障的降本增效方法探索(下)

文章来源&#xff1a;公众号ID-布博士&#xff08;擎创科技资深产品专家&#xff09; 哈喽~上期内容我们分享了传统调用链系统与CMDB系统的缺陷、服务所有权模型是什么、服务所有权模型分类。这期我们来说一说如何落地服务所有权模型&#xff0c;以及好用的模型推荐&#xff0…

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(二)

向量数据库选择哪种近似搜索算法&#xff0c;选择合适的集群规模以及集群设置调优对于知识库的读写性能也十分关键&#xff0c;主要需要考虑以下几个方面&#xff1a; 向量数据库算法选择 在 OpenSearch 里&#xff0c;提供了两种 k-NN 的算法&#xff1a;HNSW (Hierarchical…

Java零基础——SpringMVC篇

1.SpringMVC介绍 SpringMVC是Spring框架中的一个组件&#xff0c;是一个轻量级的web的MVC框架&#xff0c;充当controller,其本质就是一个Servlet。 1.1 传统Servlet的不足 每个请求&#xff0c;都需要定义一个Servlet。虽然可以在service方法中&#xff0c;根据业务标识进行…