美文网首页
26. java虚拟机总结-垃圾回收器-G1(九)

26. java虚拟机总结-垃圾回收器-G1(九)

作者: 任振铭 | 来源:发表于2020-08-05 07:48 被阅读0次
    G1 的回收原理是什么?为什么 G1 比传统 GC 回收性能好?
    
    为什么 G1 如此完美仍然会有 ZGC?
    

    CMS 垃圾回收器的一个极端场景(而且是经常发生的场景)
    在发生 Minor GC 时,由于 Survivor 区已经放不下了,多出的对象只能提升(promotion)到老年代。但是此时老年代因为空间碎片的缘故,会发生 concurrent mode failure 的错误。这个时候,就需要降级为 Serail Old 垃圾回收器进行收集。这就是比 concurrent mode failure 更加严重的 promotion failed 问题。一次简单的 Major GC,竟然能演化成耗时最长的 Full GC。最要命的是,这个停顿时间是不可预知的。

    gc.jpg
    G1( Garbage­First GC)垃圾回收器是如何解决这个问题的?

    首先定义一个停顿时间,然后反向推算收集内容,不要求每次都把垃圾清理的干干净净。我们要求 G1,在任意 1 秒的时间内,停顿不得超过 10ms,这就是在给它制定 KPI。G1 会尽量达成这个目标,它能够推算出本次要收集的大体区域,以增量的方式完成收集。
    -XX:MaxGCPauseMillis=10

    什么是G1垃圾回收器

    其他的回收器,都是对某个年代的整体收集,收集时间上自然不好控制。G1 把堆切成了很多份,把每一份当作一个小目标,部分上目标很容易达成。
    G1 的全称是 Garbage­First GC,为了达成上面制定的 KPI,它和前面介绍的垃圾回收器,在对堆的划分上有一些不同。

    面试题:G1 有年轻代和老年代的区分吗?
    
    G1老年代和年轻代划分.jpg

    G1 也是有 Eden 区和 Survivor 区的概念的,只不过它们在内存上不是连续的,而是由一小份一小份组成的。这一小份区域的大小( 1M 到 32M 字节之间的一个 2 的幂值数)是固定的,名字叫作小堆区(Region)。小堆区可以是 Eden 区,也可以是 Survivor 区,还可以是 Old 区。所以 G1 的年轻代和老年代的概念都是逻辑上的。

    Region 的大小,可以通过参数进行设置:
    -XX:G1HeapRegionSize=<N>M

    但假如对象太大,一个 Region 放不下了怎么办?注意图中有一块面积很大的黄色区域,它的名字叫作 Humongous Region,大小超过 Region 50% 的对象,将会在这里分配。

    那么,回收的时候,到底回收哪些小堆区呢?是随机的么?
    这当然不是。事实上,垃圾最多的小堆区,会被优先收集。这就是 G1 名字的由来。

    G1 的垃圾回收过程

    在逻辑上,G1 分为年轻代和老年代,但它的年轻代和老年代比例,并不是那么“固定”,为了达到 MaxGCPauseMillis 所规定的效果,G1 会自动调整两者之间的比例。
    如果你强行使用 -Xmn 或者 -XX:NewRatio 去设定它们的比例的话,我们给 G1 设定的这个目标将会失效。

    G1 的回收过程主要分为 3 类:

    (1)G1“年轻代”的垃圾回收,同样叫 Minor GC,这个过程和我们前面描述的类似,发生时机就是 Eden 区满的时候。
    (2)老年代的垃圾收集,严格上来说其实不算是收集,它是一个“并发标记”的过程,顺便清理了一点点对象。
    (3)真正的清理,发生在“混合模式”,它不止清理年轻代,还会将老年代的一部分区域进行清理。


    g1回收过程.jpg

    在 GC 日志里,这个过程描述特别有意思,(1)的过程,叫作 [GC pause (G1 Evacuation Pause) (young),而(2)的过程,叫作 [GC pause (G1 Evacuation Pause) (mixed)。Evacuation 是转移的意思,和 Copy 的意思有点类似。

    这三种模式之间的间隔也是不固定的。比如,1 次 Minor GC 后,发生了一次并发标记,接着发生了 9 次 Mixed GC。

    相关文章

      网友评论

          本文标题:26. java虚拟机总结-垃圾回收器-G1(九)

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