g1垃圾回收器

简述

g1垃圾收集器是Java7引入的一款垃圾收集器,全称Garbage-Frist Collector。
G1是一个分代的,增量的,并行与并发的标记-复制算法 垃圾回收器,G1设计的目的是为了应对越来越大的内存以及越来越多的处理器数量。
G1还有一个重要的特性-软实时:实时回收是指对每一次垃圾回收所造成的停顿时间都在限定时间之内。软实时是指G1允许设置一个限定值,G1会努力控制每一次Gc所造成的停顿都在限定时间之内,但是并不保证每一次gc造成的停顿都能满足要求。停顿时间可以的设置可以通过-XX:MaxGCPauseMillis参数设置。如果需要设置此参数,要慎重,过大的话没有意义,过小则会导致频繁触发回收,降低回收效率。

1. Region

G1 region划分

不同于传统分代垃圾回收器,将堆空间固定的划分为新生代与老年代2个内存区域,g1采用分区的概念,将整个堆分为若干个大小相等的内存区域。每个内存区域就是一个region,这些region不在是固定的属于新生代和老年代,他既可以是新生代,也可以是老年代,Region是g1最小回收单元。

通常是把Java堆划分为2048个大小相等的独立region,每个region大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1-32MB,且必须为2的N次幂。

虽然g1仍然保留新生代和老年代的概念,但新生代和老年代不在是固定的了,而是一系列区域(不需要连续,逻辑连续即可)的动态集合。由于G1这种基于region回收的方式,可以预测停顿时间,g1会根据每个region里面垃圾价值的大小,在后台维护一个优先级列表,每次根据用户设定的允许收集停顿时间,优先处理收益价值最大的region。

Humongous Region 的处理

  • 定义
    Humongous Region是G1对巨大对象的特殊处理,当一个对象的大小超过了Region的50%,该对象会被认为是一个矩形对象。
  • 一个巨型对象会占据一个或者多个连续Region(如果没有找到连续的Region则会进行担保Full GC)。其中起始分区被标记为起始巨型(Start Humongous),后续分区被标记为连续巨型(Continues Humongous)。
  • 巨型分区被认为是老年代的一部分,但是巨型对象的晋升成本很高,因此对于巨型对象,G1在年轻代收集时就会探测其存活性,一旦死亡就会在当次回收释放掉。另外在混合收集周期,因为巨型对象的独占性,巨型对象死亡便是整个分区的死亡,分区就不会再被放入CSet等待回收,而是在清理阶段直接释放掉。

因为G1采用了分区的概念,所以有些对象会存在于不同的分区中,针对这种情况,g1需要知道回收对象的分布情况,所以有了Cset、Rest的概念。

2.CSet

  • CSet全称Collection Set,CSet中保存着每次GC中要回收的目标分区,回收分区内的存活对象会被复制到新分配的空闲分区中。
  • 因为年轻代是整体回收,所以无论在年轻代收集还是混合收集,所有的年轻代垃圾都会被放入CSet。老年代分区的回收只会在混合收集中涉及,在混合收集中,根据收益率将回收收益率较高的候选老年代分区放入CSet等待回收。

其实Cset的作用就是记录哪些Region需要回收

3.Rset

Rset全称Remember Set(记忆集合)。
每个Region的Rset都记录着 当前Region中的引用对象 的外部老年代所在的Region_card。

Rest的目的是为了记录当前Region之外的引用来源。这样在对Cset分区进行复制回收时,就可以精准的知道该复制对象的引用来自哪里,从而在复制完成后精确的找到应用进行更新,而不用进行全堆扫描在确定应用关系。

4. 年轻代收集(Young GC)

  • 触发条件
    当年轻代满时就会触发年轻代收集,回收年轻分区,并将存活次数达到晋升标准的对象移入老年代。
  • 年轻代分区的收集是stop the world的
    用户线程暂停,运用可达性分析法扫描所有的年轻代分区,标记gc root 直接关联引用链中的存活对象,除此之外会扫描所有年轻代分区的Rset,标记出老年代分区引用的对象对根节点进行补充,根据完整的根对象进行引用分析就获得了年轻代分区的所有存活对象。
  • 标记完成后Eden Region中的存活对象会被复制到新的Survivor Region,而Survivor Region的存活对象满足晋升标准的晋升入老年代,不满足晋升的依然被复制到新的Survivor Region。之后释放所有的年轻代分区对空间进行回收。

5.混合收集周期(Mixed GC)

  • 触发条件
    随着程序的运行,越来越多的对象晋升到老年代,当老年代堆占比达到阈值(老年代占整堆比,可以通过-XX:InitiatingHeapOccppancyPercent设置,默认45%)时就会触发混合收集,但是混合收集不会立即执行,而是会等待下一次年轻代收集。
  • 另外为了保证停顿时间
    混合收集可能只会收集老年代分区的一部分,接着就继续让应用程序运行,并在接下来的连续多次年轻代收集时触发混合收集。整个连续多次的混合收集过程被称为混合收集周期(Mixed Collection Cycle).
  • 收集次数
    通过参数-XX:G1MixedGCCountTarget控制混合周期中混合收集的最大总次数,默认为8,即整个混合收集周期会进行8次混合收集,每次至少有1/8的候选老年代分区[注5]被放入CSet中。另外通过参数-XX:G1HeapWasteParcent来设置混合收集周期的堆废物百分比,默认为5,即当老年代垃圾堆占比低于5%时,即使没达到最大总次数,混合收集周期也会停止,因为过低的垃圾堆占比会使得回收效益变的很低。
  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值