Panda白话 - G1垃圾收集器

wuchangjian2021-11-15 21:30:54编程学习

are you ready~~
知识点太多,肝一篇长文~,let us go ~~

G1 - Garbage First 垃圾收集器

What is G1:

见名思议,garbage first,垃圾优先,先回收垃圾多的region,region你还不知道是啥,往下看

先来看一张java 发布时间线,G1在JDK 7 发布,在JDK 9之后成为默认垃圾收集器
在这里插入图片描述

先来简单说下jdk已经提供的几种垃圾收集、如下图:

在这里插入图片描述

Young Generation - 年轻代:

  • Serial-串行 : 单线程、STW(stop the world)-暂停所有用户线程 、复制算法
  • ParNew : 并行垃圾收集器 、 复制算法
  • Parallel Scavenge - 并行垃圾收集器 、复制算法
  • G1

Tenured Generation - 老年代:

  • CMS - 并发垃圾收集器 、 标记-清除算法

  • Serial Old - Serial 的老年代版、标记-整理算法

  • Parallel Old - Parallel Scavange 的老年代版、标记-整理算法

  • G1
    note:

  • Parallel 和ParNew 都是并行GC Collector,此处并行只是说多个GC线程并行进行垃圾收集动作,还是要STW,暂停所有用户线程的

  • Parallel 和ParNew 都是并行收集、都是标记-整理算法,Parallel 关注Throughput-吞吐量,也称吞吐量优先收集器
    吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)
    Parallel Scavenge 提供了两个参数控制吞吐量:

-XX:MaxGCPauseMillis  - GC最大暂停时间(毫秒)、JVM没有指定默认值
-XX:GCTimeRatio =99 - GC时间占比  、 只能取0到100的整数,默认99,即  1/(1+99)  =  1%

Parallel Scavenge 还提供了1个参数 - 很牛:

-XX:+UseAdaptiveSizePolicy  - 启动GC自适应的调节策略、jdk8默认启用
-XX:-UseAdaptiveSizePolicy - 关闭GC自适应的调节策略

自适应嘛,顾名思义,JVM自己动态调整来提供最合适的停顿时间或最大的吞吐量,
启动之后,一下参数不用自己配啦,根据运行情况动态调整。

-Xmn: - 年轻代大小、一般为1/4 (-Xmx - 最大堆内存大小)
-XX:NewRatio:2(默认)- 新生代与老年代的比例,即Young = 1/3 (Heap)、Old = 2/3 (Heap)
-XX:SurvivorRatio:8(默认) - 新生代中Eden:Survivor0:Survivor1 = 8:1:1
  • 既然Parallel Scavenge 这么厉害还要ParNew干啥呢?ParNew也很重要,它是唯一可以和CMS搭配使用的新生代收集器
  • CMS是G1之前真正实现并发GC的Collector,并发指的是GC线程可以和用户线程交替获得CPU时间片,即用户无感知的情况下就完成了GC(当然它也有STW的阶段,G!的mixed GC 同CMS类似,后面详细介绍)
    宏观上来看就是这样的、如下图,GC的同时,用户线程也在并发进行。在这里插入图片描述
  • CMS使用的是Mark-Sweep (标记-清除)算法,会产生很多内存碎片、如下图
    在这里插入图片描述

G1垃圾收集器强势来袭,赋予了取代CMS的使命

G1 有哪些特性 - 牛在哪里:

  • 最小时延
  • 最大吞吐量
  • 并发+并行
  • 引入分区思想
  • 可预测的停顿时间模型 - soft real-time (软实时)

G1之前内存划分 - 分代 - 如下图 -

  • 年轻代和老年代内存空间物理连续
  • Permanent - 永久代 在jdk 8 被干掉了
  • 年轻代收集器都采用复制算法,通过s0、s1空间复制实现
    在这里插入图片描述
    G1将内存重新划分,引入了Region(分区)的概念、先上图:

在这里插入图片描述

  • G1将heap划分为2048个大小相等的Region

  • 每个Region逻辑连续,物理不连续

  • GC是以Region为单位进行的

  • Region有5种类型

    • Eden - 伊甸园,新生代的eden区
    • Survivor - 存活区,新生的s0、s1区
    • Old - 老年代
    • Humongous - 巨无霸对象区,简单说一下吧,就是一个对象大小>1/2 eden,那它就是巨大对象,直接放到H区,H区可能占几个连续的Region
    • free - 空闲分区
  • 每个Region是哪种类型不是固定的,一个Region被GC释放后就是free分区,下次被分配为哪种类型都有可能

先理解到这个维度吧,逐步递进:
G1 就是把堆内存给切豆腐了,不同的Region不同的策略,分而治之,一块一块的管理,总体还是分代思想,分为新生代和老年代,GC分为Young GC 和 Mixed Gc ,也是以Serial Old Full GC 做担保机制

G1 - 参数设置 :

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

-XX:G1HeapRegionSize   -  指定每个region的大小 ,2的n次幂,1MB - 32MB

-XX:G1NewSizePercent - 新生代占总堆最小百分比、默认值5%

-XX:G1MaxNewSizePercent - 新生代占总堆最大百分比、默认值60%

-XX:MaxGCPauseMillis - GC暂停时间,默认200ms

-XX:NewRatio - 老年代/年轻代,默认值 2,即1/3 年轻代,2/3 老年代

Young GC

  • 触发时机:

    • 新的对象创建会放入Eden区
    • Eden区满、G1会计算当前Eden区GC大概耗时多久
    • 如果回收时间远<-XX:MaxGCPauseMills,则分配空闲分区加入Eden 区存放新创建的o,
    • 如果回收时间接近-XX:MaxGCPauseMills,则触发一次Young GC
    • 年轻代初始占总堆5%,随着空闲分区加入而增加,最多不超过60%
  • Young GC 会回收整个Eden区和Survivor 区

  • Young GC 会STW(stop the world),暂停所有用户线程

  • 回收过程:

    • phase one - 扫描根
    • phase two - 更新RSet
    • phase three - 处理RSet
    • phase four - 复制对象
    • phase five - 处理引用

相关文章

2021-11-26整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果...

python实例九

循环标记法和break的区别 循环标记法只能结束本次循环:  br...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。