美文网首页
GC:垃圾回收算法

GC:垃圾回收算法

作者: Robin92 | 来源:发表于2020-04-16 00:44 被阅读0次

    简述 G1、ZGC

    • G1 之前都是将内存看做两块整体(Young 和 Old 区)。
    • G1 是将内存分成一小块一小块的 分而治之,一部分在运行线程时,另一部分在进行回收。
    • ZGC 是 G1 分块有大有小。

    CMS 有两个缺点,一是产生碎片,二是产生浮动垃圾。它的最大问题是在触发 FullGC 时是单线程的,所以太慢了。

    G1

    G1 又叫 Garbage First,意思是当决定要进行垃圾回收时,它先进行 垃圾最多 的 Region 的回收。

    G1 进行的是分而治之来处理的。

    image.png

    G1 和 CMS 都用的是并发收集,他们的算法也一样都是 三色标记算法
    ZGC 和 Shenandoah 用的算法是 颜色指针

    并发标记算法G1

    概念

    • CSet,Collection Set,指一组可被回收的分区的集合。
    • RSet,Remember Set,在每一个 Region 中都有一个 Hash Set 记录了其他 Region 对象对本 Region 的引用。
    • Card Table,在 YGC 时需要扫描整个 OLD 区的话效率会很低,所以有了 Card Table 的概念,它将 Old 区分为不同的 Card 组成一个 Table。如果有一个 OLD 区的 Card Table 中有对象指向 Y 区,就将它设为 Dirty,用 Bitmap 来实现,这样下次只需要扫描 Dirty Card 就可以找到它。

    三色标记法

    黑 -> 灰 -> 白(由黑色向白色延伸)

    • 黑色表示自身和成员变量均被标记完成。
    • 灰色表示自身被标记完了,但我所引用的对象还未标记。
    • 白色是指自己还没有被标记。

    漏标

    只有在下面两个条件同时满足都会发生漏标:

    • Remark 过程中黑色对象的引用指向了白色对象
    • 与此同时,灰色对象对白色对象的指向丢失了
    image.png

    所以,解决漏标只需要打破其中一个条件即可。所以解决方法有两种,
    一种是跟踪 A->D 的增加;
    另一种是跟踪 B->D 的消失。
    其分别为:

    • Incremental Update,增量更新,关注引用的增加,当 A->D 发生时,把黑色重新标记为灰色。(CMS 用了它)
    • SATB,Snapshot At The Beginning,在开始时进行一个快照,当 B->D 消失的时候,把这个 引用 推到 GC 的堆栈,保证 D 还能被扫描到。(G1使用这种)

    SATB 这种形式,会在 GC 中创建一个栈,这个栈只存灰色对象指向白色对象的 引用,注意是 引用->)。

    G1 为什么要用SATB

    因为前者会重新扫描 A。而后者只需要在栈中重新扫描就可以找到 D(都是重新标记阶段)。因为 RememberSet 的存在,在 RSet 中没有人用到 D 就可以认为 D 为垃圾。即它不需要再去扫描整个堆,所以效率更快。

    RSet 会记录别人的引用指向我这里面的所有引用。
    写屏障,它的意思就是由于 RSet 的存在,每次给对象赋引用的时候,做一些额外的操作,这就是写屏障(概念很无聊)。

    G1 有 FGC 吗

    有 FGC,当内存不够用时,就会进行 FGC。

    G1 触发 FGC 了该怎么办

    应该尽量避免触发 FGC。

    • 扩内存
    • 增加 CPU
    • 调低 MixGC 的阈值。(MixGC 就是一套完整的 CMS)

    图示三色标记法: https://making.pusher.com/golangs-real-time-gc-in-theory-and-practice/

    相关文章

      网友评论

          本文标题:GC:垃圾回收算法

          本文链接:https://www.haomeiwen.com/subject/abbkvhtx.html