文章目录

  • G1垃圾收集器
    • 定义
    • G1的优势
    • G1架构
    • G1 内存布局
    • G1可以让用户自己设置应用暂停时间,为什么可以做到这一点?
  • G1 缺点
    • G1 GC模式
      • G1 Young GC
      • Mixed GC
  • 什么时候用G1
  • G1的瓶颈:
    • 整体停顿分析
  • ZGC 垃圾收集器
    • 核心原理
    • 核心收集流程
  • ZGC 缺点

G1垃圾收集器

引入问题G1 垃圾收集器架构,为什么可以指定时间。?

定义

G1 即 garbage first ,意思是优先处理那些垃圾多的内存块的意思。
G1 适用于新生代 和 老年代。是利用复制算法实现

G1是一款可以实现高吞吐量,同时可以保证GC停顿时间不会很长的垃圾收集器

G1的优势

  • 适用于大容量的内容,多核的处理器
  • 可以实现并发收集垃圾,和用户程序能同时运行
  • 整理内存不需要大量的暂停时间
  • 能保持较高吞吐量,可以预测GC停顿时间

G1架构

传统的垃圾收集器是将堆内存划分为几块固定大小的内存区域,eden , survivor , old 。
而G1 垃圾收集器是将内存划分了很多个小块Region,每一个小块都会被标记为eden 、 survivor 或者old 。
这样做的好处是,内存块的粒度更小,可以更加细化的管理内存,这样每一次垃圾回收就不需要把一大块的eden或者old内进行回收,只需要针对小块的region进行回收即可,减少停顿时间,这样还可以有效的避免内存碎片的问题,因为每次垃圾回收都是清空一整块的region区域,避免的内存碎片。这些小块的region可以高度并行化收集,有效的减少停顿时间。

G1 内存布局

G1的各代存储地址是不连续的,每一代都使用了n个不连续的大小相同的Region,每个Region占有一块连续的虚拟内存地址。如下图所示

在上图中,我们注意到还有一些Region标明了H,它代表Humongous,这表示这些Region存储的是巨大对象(humongous object,H-obj),即大小大于等于region一半的对象。H-obj有如下几个特征: * H-obj直接分配到了old gen,防止了反复拷贝移动。 * H-obj在global concurrent marking阶段的cleanup 和 full GC阶段回收。 * 在分配H-obj之前先检查是否超过 initiating heap occupancy percent和the marking threshold, 如果超过的话,就启动global concurrent marking,为的是提早回收,防止 evacuation failures 和 full GC。

为了减少连续H-objs分配对GC的影响,需要把大对象变为普通的对象,建议增大Region size。

一个Region的大小可以通过参数-XX:G1HeapRegionSize设定,取值范围从1M到32M,且是2的指数。如果不设定,那么G1会根据Heap大小自动决定

G1可以让用户自己设置应用暂停时间,为什么可以做到这一点?

G1 回收大概有四步(全局并发标记):

  1. 初始标记:找出跟gc root 直接关联的对象,这里会短暂的暂停用户线程,停止应用
  2. 并发标记:根据可达性分析,找到其他存活的对象,这一步可以用户线程并发执行。
  3. 最终标记: 修正在并发标记期间因为用户程序而改变的数据,需要暂停用户线程。
  4. 筛选回收:对各个region的回收价值和成本进行排序,根据用户期望的GC 停顿时间制定回收计划。需要暂停用户线程。

因为筛选回收只回收一部分价值高的Region区的垃圾对象,时间是用户可控制的,而且停顿用户线程将大幅提高收集效率。回收时,采用“复制”算法,从一个或多个Region复制存活对象到堆上的另一个空的Region,并且在此过程中压缩和释放内存,避免内存碎片

所以能设置时间的主要原因就是在第四步里面,G1垃圾收集器不会回收整代内存,而是对每一块region进行排序,具体回收多少要看用户设置的停顿时间,优先回收那些垃圾最多的region区域

G1 缺点

对一些内存很小的应用,G1对内存进行部分回收根本不够用,所以始终都要进行整个堆的回收,那么G1反而不适合,因为G1算法更加复杂,可能比其他回收器还要差,因为G1适用于内存稍大一点的应用,一般来说至少4G以上。
在某些情况下,G1触发了Full GC,这时G1会退化使用Serial收集器来完成垃圾的清理工作,它仅仅使用单线程来完成GC工作,GC暂停时间将达到秒级别的。整个应用处于假死状态,不能处理任何请求

G1 GC模式

G1 Young GC

所有年轻代里的Region

Young GC主要是对Eden区进行GC,它在Eden空间耗尽时会被触发。在这种情况下,Eden空间的数据移动到Survivor空间中,如果Survivor空间不够,Eden空间的部分数据会直接晋升到年老代空间。Survivor区的数据移动到新的Survivor区中,也有部分数据晋升到老年代空间中。最终Eden空间的数据为空,GC停止工作,应用线程继续执行。

注意全局并发标记(global concurrent marking)的那几个阶段,并不是young GC 里面必须的步骤,只是“全局并发标记”会利用young gc暂停的那个空间,顺便做一下标记。全局并发标记是为mixed gc服务的

global concurrent marking,它的执行过程类似CMS,但是不同的是,在G1 GC中,它主要是为Mixed GC提供标记服务的,并不是一次GC过程的一个必须环节。

Mixed GC

年轻代里的Region + 回收价值高的老年代Region

选定所有年轻代里的Region,外加根据global concurrent marking统计得出收集收益高的若干老年代Region。在用户指定的开销目标范围内尽可能选择收益高的老年代Region。 (global concurrent marking即全局并发标记)

  • Mixed GC时机
    Young GC发生的时机大家都知道,那什么时候发生Mixed GC呢?其实是由一些参数控制着的,另外也控制着哪些老年代Region会被选入CSet。 * G1HeapWastePercent:在global concurrent marking结束之后,我们可以知道old gen regions中有多少空间要被回收,在每次YGC之后和再次发生Mixed GC之前,会检查垃圾占比是否达到此参数,只有达到了,下次才会发生Mixed GC。 * G1MixedGCLiveThresholdPercent:old generation region中的存活对象的占比,只有在此参数之下,才会被选入CSet。 * G1MixedGCCountTarget:一次global concurrent marking之后,最多执行Mixed GC的次数。 * G1OldCSetRegionThresholdPercent:一次Mixed GC中能被选入CSet的最多old generation region数量。

除了以上的参数,G1 GC相关的其他主要的参数有:

  • 参数 含义
    -XX:G1HeapRegionSize=n 设置Region大小,并非最终值
    -XX:MaxGCPauseMillis 设置G1收集过程目标时间,默认值200ms,不是硬性条件
    -XX:G1NewSizePercent 新生代最小值,默认值5%
    -XX:G1MaxNewSizePercent 新生代最大值,默认值60%
    -XX:ParallelGCThreads STW期间,并行GC线程数
    -XX:ConcGCThreads=n 并发标记阶段,并行执行的线程数
    -XX:InitiatingHeapOccupancyPercent 设置触发标记周期的 Java 堆占用率阈值。默认值是45%。这里的java堆占比指的是non_young_capacity_bytes,包括old+humongous

避免使用以下参数:
避免使用 -Xmn 选项或 -XX:NewRatio 等其他相关选项显式设置年轻代大小。固定年轻代的大小会覆盖暂停时间目标,应该让jvm自己去适配大小

学习参考:
https://tech.meituan.com/2016/09/23/g1.html (美团资料)
https://www.cnblogs.com/aspirant/p/8663872.html(阿)
https://zhuanlan.zhihu.com/p/191253113
https://blog.csdn.net/qq_38294614/article/details/107746331

什么时候用G1

官网:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases
(1)50%以上的堆被存活对象占用
(2)对象分配和晋升的速度变化非常大
(3)垃圾回收时间比较长

G1的瓶颈:

在介绍ZGC之前,首先回顾一下CMS和G1的GC过程以及停顿时间的瓶颈。CMS新生代的Young GC、G1和ZGC都基于标记-复制算法,但算法具体实现的不同就导致了巨大的性能差异。

标记-复制算法应用在CMS新生代(ParNew是CMS默认的新生代垃圾回收器)和G1垃圾回收器中。标记-复制算法可以分为三个阶段:

  • 标记阶段,即从GC Roots集合开始,标记活跃对象;
  • 转移阶段,即把活跃对象复制到新的内存地址上;
  • 重定位阶段,因为转移导致对象的地址发生了变化,在重定位阶段,所有指向对象旧地址的指针都要调整到对象新的地址上。
    下面以G1为例,通过G1中标记-复制算法过程(G1的Young GC和Mixed GC均采用该算法),分析G1停顿耗时的主要瓶颈。G1垃圾回收周期如下图所示:

学习参考美团博客:https://zhuanlan.zhihu.com/p/170572432

标记阶段停顿分析

  • 初始标记阶段:初始标记阶段是指从GC Roots出发标记全部直接子节点的过程,该阶段是STW的。由于GC Roots数量不多,通常该阶段耗时非常短。
  • 并发标记阶段:并发标记阶段是指从GC Roots开始对堆中对象进行可达性分析,找出存活对象。该阶段是并发的,即应用线程和GC线程可以同时活动。并发标记耗时相对长很多,但因为不是STW,所以我们不太关心该阶段耗时的长短。
  • 再标记阶段:重新标记那些在并发标记阶段发生变化的对象。该阶段是STW的。

清理阶段停顿分析

清理阶段清点出有存活对象的分区和没有存活对象的分区,该阶段不会清理垃圾对象,也不会执行存活对象的复制。该阶段是STW的。

复制阶段停顿分析

复制算法中的转移阶段需要分配新内存和复制对象的成员变量。转移阶段是STW的,其中内存分配通常耗时非常短,但对象成员变量的复制耗时有可能较长,这是因为复制耗时与存活对象数量与对象复杂度成正比。对象越复杂,复制耗时越长。

整体停顿分析

在四个过程中,
初始标记因为值标记GC root对象耗时较短。
并发标记可以不考虑,并发执行。
重新标记阶段,因为对象数少,耗时也短。
清理阶段因为内存分区数量少,耗时也短。(清点出有存活对象的分区和没有存活对象的分区,该阶段不会清理垃圾对象)
转移阶段因为要处理所有存活对象,包含复制对象属性,耗时会较长。因为G1的瓶颈主要是标记-复制中的转移阶段stw.

这时如果需要进一步减少停顿时间,就需要在复制阶段做文章

ZGC 垃圾收集器

JDK11新引入的ZGC收集器,不管是物理上还是逻辑上,ZGC中已经不存在新老年代的概念了,会分为一个个page,当进行GC操作时会对page进行压缩,因此没有碎片问题

ZGC 采用的是标记复制算法,可以低延迟的垃圾回收,停顿时间短。适合应用在更大内存和追求更低延迟场景
停顿时间短的原因主要是因为再对象复制转移阶段,采用的了对象的并发转移技术,对象的转移和应用线程可以同时进行。
对象转移过程中,地址会发生变化,如何保证应用线程访问的对象不会出错。

核心原理

ZGC垃圾回收过程几乎全部是并发,实际STW停顿时间极短,不到10ms。这得益于其采用的着色指针和读屏障技术。
主要采用了着色指针和读屏障技术
着色指针: 使用“空间换时间”思想,去降低GC停顿时间,这个空间是ZGC设置的虚拟空间
读屏障:将读出来的指针更新到对象的新地址上,保证访问的都是对象的新地址

知识点:
写屏障保证了在屏障之前的操作会强制更新到主内存,对其他线程是可见的,这种显示调用防止了指令重排序
读屏障可以让高速缓存中的数据失效,强制从主内存中加载数据,避免缓存不一样

核心收集流程

ZGC在回收周期大概分几步:原理参考链接https://zhuanlan.zhihu.com/p/170572432

初始标记
并发标记
重新标记
并发转移准备
初始转移
并发转移

整个过程中的停顿只发生在初始标记,重新标记,初始转移阶段。
初始标记和初始转移分别都只需要扫描所有GC Roots,其处理时间和GC Roots的数量成正比,一般情况耗时非常短;
再标记阶段STW时间很短,重新标记的对象也不多,最多1ms,超过1ms则再次进入并发标记阶段。
即,ZGC几乎所有暂停都只依赖于GC Roots集合大小,停顿时间不会随着堆的大小或者活跃对象的大小而增加。
与ZGC对比,G1的转移阶段完全STW的,且停顿时间随存活对象的大小增加而增加,因为需要复制对象所有属性等会耗时很长。

ZGC 缺点

对吞吐量优先的场景,ZGC可能并不适合
因为,第一ZGC 是单代垃圾收集器,CMS这种是分代回收,单代回收的话每次处理的对象更多,更消耗cpu资源,垃圾收集时间长。第二,zgc采用的是读屏障技术,需要消耗额外的计算资源

  • 垃圾收集器跟内存大小的大致关系(不精确,需要根据实际环境测试)
    Serial:几十兆
    PS:上百兆 ~ 4G
    CMS:4G ~ 10G
    G1:10G~上百G
    ZGC: 4T - 16T(JDK13)

G1和ZGC垃圾收集器相关推荐

  1. java垃圾收集器zgc_java虚拟机ZGC垃圾收集器的实现方法

    java虚拟机垃圾回收算法和工具是我们在学习java虚拟机的时候需要重点掌握的编程知识,而今天我们就通过案例分析来了解一下,java虚拟机ZGC垃圾收集器的实现方法. 1.染色指针 HotSpot的垃 ...

  2. JVM垃圾回收——ZGC垃圾收集器

    目录 一.什么是ZGC垃圾收集器 二.ZGC的内存模型 三.收集过程 染色指针 多重映射 收集过程 四.优缺点 五.参数配置 一.什么是ZGC垃圾收集器 ZGC(Z Garbage Collector ...

  3. 深入理解JVM - ZGC垃圾收集器

    如果下面的一些概念有些不清楚的可以先看深入理解JVM - 垃圾收集器和深入理解JVM - Shenandoah垃圾收集器. ZGC(Z Garbage Collector)是一款由Oracle公司研发 ...

  4. 详解ZGC垃圾收集器

    从G1垃圾收集器开始,后面的垃圾收集器都不再将堆按照新生代和老年代作为整体进行回收,都采用了局部收集的设计思想. 可能是由于G1作为第一代局部收集的垃圾收集器,所以它继续保留了新生代和老年代的概念,笔 ...

  5. ZGC垃圾收集器(-XX:+UseZGC)

    ZGC在jdk11只支持Linux版本,4TB的内存,STW时间控制在10ms内:jdk16已经支持16TB的内存,STW时间不超过1ms,下面主要针对jdk11版本的详解 一.堆内存结构 ZGC堆内 ...

  6. G1垃圾收集器深度剖析

    G1垃圾收集器深度剖析 一.G1垃圾收集器概述 1.1 思考 开始学习前,抛出两个常见面试问题:1.G1的回收原理是什么?为什么G1比传统的GC回收性能好?2.为什么G1如此完美仍然会有ZGC?简单的 ...

  7. (八)JVM成神路之GC分区篇:G1、ZGC、ShenandoahGC高性能收集器深入剖析

    引言 在<GC分代篇>中,我们曾对JVM中的分代GC收集器进行了全面阐述,而在本章中重点则是对JDK后续新版本中研发推出的高性能收集器进行深入剖析,但在开始前,先来看看JDK的发布记录中关 ...

  8. Oracle提议将G1作为Java 9的默认垃圾收集器

    Oracle正在考虑将JEP 248包含到Java 9的JEP列表中,即在服务器配置中将G1作为默认垃圾收集器.该决定在Java社区引发了一些争论,许多人都认为并发标记和扫描(CMS)收集器可能更合适 ...

  9. JVM性能调优实践:G1 垃圾收集器介绍篇

    前言 前面两篇主要整理了性能测试的主要观察指标信息:性能测试篇,以及JVM性能调优的工具:JVM篇.这一篇先简单总结一下GC的种类,然后侧重总结下G1(Garbage-First)垃圾收集器的分代,结 ...

最新文章

  1. 微软支持BCH支付方式 曾三次暂停BTC支付
  2. CactiEZ V10.1 中文版 Cacti中文解决方案+使用教程(1)
  3. Java内部类手机专卖店_Java:内部类
  4. 1.2执行更高级的线程任务(Performing More Advanced Thread Tasks)
  5. 帆软 动态改变填报数据库表;数据分析亦可用此方法
  6. 使用Koa2重构博客项目
  7. 计算机图形学完整笔记(七):曲线曲面 - 1
  8. 安装ubuntu18.04报:failed to load ldlinux.c32
  9. 寄存器PLC地址与寄存器modbus协议地址
  10. 常见查找算法--(快速查找或二分查找)
  11. 解决 当前上下文中不存在名称 c#
  12. 《缠中说禅108课》28:下一目标:摧毁基金
  13. 在godot的canvas_item着色器中构建逆投影矩阵和逆视图矩阵
  14. tomcat配置https(jks)证书,启动后提示Keystore was tampered with, or password was incorrect
  15. 小升初数学知识体系梳理
  16. #第二章 数理文化的起源2.1文化概述
  17. 1:算法php/go [反转链表;LRU缓存结构 ;判断链表中是否有环]
  18. Word控件Spire.Doc 【页面设置】教程(9) 如何在 C# 中添加行号
  19. 京东商品及评论 数据采集
  20. Js构造函数创建Person类

热门文章

  1. Flex布局教程:语法篇(转载阮一峰)
  2. 对JSON数据进行排序
  3. android rom修改小白有福了
  4. 全是技巧!ZBrush雕刻手部教程赶紧收藏!
  5. Beaglebone Black基本操作(Debian)
  6. 转载 一整套美团面经
  7. org.apache.jasper.JasperException 解决思路
  8. 操作系统实验—设备管理
  9. 操作系统实验一 Linux基本操作|实验二 进程管理
  10. 团队作业(五)-笔记app top5