JVM系列(5)--Garbage Collectors 常见垃圾回收器

在这里插入图片描述

一. 年轻代垃圾回收器

1. Serial

  • a stop-the-world, copying collector which uses a single GC thread.
  • STW/stop-the-world: 回收垃圾时,工作线程需要停下来

2. Parallel Scavenge(PS)

  • a stop-the-world, copying collector which uses multiple GC threads.
    多线程清理垃圾

3. ParNew(Parallel New)

  • a stop-the-world, copying collector which uses multiple GC threads. 和Parallel Scavenge一样也是多线程清理垃圾

  • It differs from “Parallel Scavenge” in that it has enhancements that make it usable with CMS. 但是做了一些增强,可以配合CMS使用

  • For example, “ParNew” does the synchronization needed so that it can run during the concurrent phases of CMS. 例如,“ParNew”执行所需的同步,以便在并发期间运行

  • PN vs. PS

PN响应时间优先(配合CMS), PS吞吐量优先

二. 老年代垃圾回收器

1. Serial Old

a stop-the-world, mark-sweep-compact collector that uses a single GC thread

2. Parallel Old

a compacting collector that uses multiple GC threads.

3. CMS(Concurrent Mark Sweep)

  1. 概念
  • a mostly concurrent, low-pause collector.
  • 4 phases
  1. initial mark: 只标记最根上的对象,STW
  2. concurrent mark: 并发标记,可以和工作线程一起工作,GC过程80%的时间都花在这里了
  3. remark:重新标记在并发标记过程中产生的新垃圾,STW
  4. concurrent sweep:并发清理,会产生新的垃圾即浮动垃圾,浮动垃圾需要等下一次CMS给清理掉 STW
  1. 缺点

CMS如果出现了问题,会调用SO使用单线程进行标记压缩

  1. 解决方案
  • memory fragmentation: -XX:CMSFullGCsBeforeCompaction 默认为0,指的时经过多少次FGC才进行压缩

产生内存碎片,可用空间如果不够了就需要SO来标记压缩

  • floating garbage:
  • Concurrent Mode Failure -XX:CMSInitiatingOccupancyFraction 92% 可以降低这个阈值,让CMS保持老年代有足够的空间
  • SerialOld

三. 常用垃圾回收器组合

  1. Serial + Serial Old
  2. Parallel Scavenge + Parallel Old
  3. ParNew + CMS

四. Remark阶段的算法

1. 不同的垃圾回收器如何进行并发标记?

CMS:三色标记 + Incremental Update算法
G1:三色标记 + SATB算法,配合G1的Rset进行
ZGC/Shenandoah:颜色指针

2. 三色标记

1. 把对象在逻辑上分为三个不同的颜色

  • 黑色:已标记完该对象是不是垃圾,而且其引用的对象也已标记完成
  • 灰色:自身标记完成,其引用的对象未标记完(白色)
  • 白色:未被标记

2. 漏标
在这里插入图片描述
3. 漏标的解决方案

  1. incremental update(增量更新)
  • 当A指向D时跟踪此引用,产生了此引用之后将A重新标记为灰色,下一次扫描时会重新扫描A的孩子们,这时D就会被找到
  • CMS使用增量更新算法,由于灰色成员要被重新扫描,效率较低
  1. snapshot at the beginning(SATB)
  • 当B->D之间的引用消失时,此时此引用是灰色->白色的引用,且没有其他已知黑色引用指向该白色引用,则将该灰白引用推到GC的堆栈,所以下一次GC还可以在堆栈中找到这个引用,白色就不会被漏标
  • G1使用SATB,配合G1的RSet,不需要扫描真个堆去查找指向白色的引用,效率会比较高

3. 颜色指针

详情请戳

五. G1

1. 概念

  • G1采用逻辑分代,物理不分代的模型
  • G1是一种服务端应用使用的垃圾回收器,目标使用在多核、大内存的机器上,它在大多数情况下可以实现指定的GC暂停时间,同时还能保持较高的吞吐量
  • When G1 GC determines that a garbage collection is nessary, it collects the regions with the least live data first (garbage first).

在这里插入图片描述

2. G1的内存分区(region)

  • G1将内存分为一个个region,region大小从1M->32M,都是2的幂次方
  • 每个region在逻辑上依然属于某一个分代
  • G1的分代有四种:
  1. Old:老年代
  2. Survivor:存活对象
  3. Eden:新生对象
  4. Humongous:大对象区域,超过单个region的50%,或跨越多个region
  • 这样的分代模型可以支持上述的 garbage first,即G1名称的由来

3. G1的特点

  • 优先回收垃圾最多的分区,但新生代依然在满了之后对整个新生代进行回收,所以新生代的对象要么被回收,要么被晋升。新生代也要分区是为了和老年代统一,方便调整分代大小
  • G1还是一种带压缩的GC,回收Old时,是将存活对象从一个分区拷贝到另一个分区,这个过程实现了局部压缩
  • G1的内存区域不是固定的,某一时间段可能是Eden,当YGC将其回收后,下次可能被当作Old使用

4. CSet

需要被回收的对象会被放到CSet中

5. RSet

每个Region都有一个Hash表,记录了其他region中的对象到本对象的引用

6. cardtable

  1. 如何确定对象是否存活?
  • 根可达算法:遍历整个老年代,老年代又可能指向年轻代
  • 由于做YGC时要扫描整个Old区,效率很低,所以设计了card table,G1将内存分为一个一个card,对象存在不同的card中,如果一个Old的cardtable中有对象指向Young区,就将其设为Dirty,下次扫描时只需扫描Dirty Card,cardtable用一个bitmap表示

7. G1产生FGC的解决方案

  1. 扩内存
  2. 提高CPU性能(垃圾回收快)
  3. 降低MixedGC的触发阈值

8. MixedGC

  1. 概念

成功完成并发标记周期后, g1 gc 从执行年轻代回收切换到执行混合回收。在混合回收中, g1 gc 可选择将一些老年代区域添加到将回收的 Eden 和幸存者区域集。添加的老年区域的确切数量由几个flag控制。g1 gc 回收足够数量的老年代区域 (通过多次混合回收) 后, g1 将恢复到执行年轻代回收, 直到下一个并发标记周期完成。

  1. MixedGC过程

YGC把年轻代活着的对象都拷贝到Survivor(Survivor to),剩下的Eden和Survivor from就可以全部回收清理了。MixedGC就是把一部分Old区的region加到Eden和Survivor from的后面,合起来称为collection set(CSet), 就是将被回收的集合,下次MixedGC evacuation把他们所有都一并清理。选old region的顺序是垃圾多的(存活对象少)优先.
整个过程和CMS相同

  • 初始标记 STW
  • 并发标记
  • 最终标记/Remark STW
  • 筛选回收/并行回收 STW
  1. 何时触发MixedGC?

YGC跟不上了,对象产生占了堆空间的45%(default),默认启动MixedGC,这个阈值可以设定

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值