快速学习垃圾收集器

serial收集器:

最古老的收集器,单线程,收集工作的时候需要暂停其他所有的工作线程(stop the world)。老年代版本:serial old
新生代复制,老年代标记-整理

在这里插入图片描述

parallel scavenge:

serial多线程版本。 关注点是吞吐量
老年代版本:parallel old
新生代复制,老年代标记整理
在这里插入图片描述

ParNew收集器:

在这里插入图片描述
serial多线程版本,主要为了减少stw,不是提升吞吐量(cpu利用率)
4核CPU就可以支持4个垃圾回收线程并行执行,可以提升4倍的性能
通常和CMS(current mark sweep)配合使用

老年代的对象存活率一般是比较高的,空间又比较大,拷贝起来并不划算

CMS:

标记清除算法
分为几个步骤:

  1. 初始标记:暂停了所有其他的工作线程(stop the world),进行标记,这一阶段标记进行的会很快。
  2. 并发标记:并发标记不会暂停其他工作线程(stop the world),但是这样就有可能造成 标记过的状态发生了改变。所以在下一个阶段,进行重新标记。
  3. 重新标记:会进行stw.就是修正并发标记过程中,用户线程继续运行造成标记变动的。主要用到的就是三色标记里面的增量更新算法。
  4. 并发清理:不会stw.开启用户线程,同时GC线程开始对未标记的区域进行清扫。如果有新增的对象,会被标记为黑色,不做任何处理。
  5. 并发重置:重置本次gc过程并发的数据

优点就是并发 停顿时间较少。

但是缺点也是很明显的,在并发标记和并发清理阶段产生的浮动垃圾,只能在下一次才能清理。
还有一个缺点就是该垃圾收集器使用的是 标记清除算法,这样会产生内存碎片。当然我们可以使用参数在执行标记清除后,进行整理 xx:+UseCMSCompactAtFullCollection(默认开启)
CMSFullGCsBeforeCompaction,每隔多少次不压缩的 Full GC 后,执行一次带压缩的 Full GC。默认值为 0,表示每次进入 Full GC 时都进行碎片整理。
而且在并发标记和并发整理阶段,因为是一边回收一边运行,也许还没有回收完成,就引发的full gc,这也就是 concurrent mode failure,这个时候会造成stw,然后之后使用serial old 单线程垃圾收集器进行回收。

关于三色标记:

黑 :所有引用扫描过
灰 :代表访问过,但是至少一个对象的引用没有被扫描过
白:未被访问过

过程:
gc是黑色的,然后初始扫描的时候是灰色的
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
同理 扫描到B
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

但是 用户干扰的情况下,指针有可能发生改变,就会产生 多标和露标的现象
针对于B, D的指向变了,变成了A
在这里插入图片描述
在这里插入图片描述
存活的对象D,竟然被标记为了垃圾!!!
在这里插入图片描述
在这个过程中 D被清理掉了

多标和漏标:

针对多标:也就是在并发标记,并发清理阶段,使用三色指针,全部当做黑色。本轮不进行擦除,下一轮进行处理。
针对漏标:被引用的对象当成垃圾错误删除,这个就是严重的bug了。
有两种解决的方案:

  1. 增量更新(Incremental update):黑色对象一1,就会变成灰色。
    在这里插入图片描述
  2. 原始快照(snapshot at the begining,SATB):
    删除的时候记录一下引用关系,等并发标记结束之后,我再去扫描一下,看一下你有没有删除。
    在这里插入图片描述
    ● CMS:写屏障 + 增量更新
    ● G1,Shenandoah:写屏障 + SATB
    ● ZGC:读屏障

关于跨代引用

一个对象,可能被新生代引用,也有可能被老年代引用。
在这里插入图片描述
这样产生一个问题,就是新生代回收的过程中,老年代也需要遍历一遍。这种成本就很高
我们在新生代 建立一个记忆集的集合
address记忆 老年代的一块区域(address 的集合) 512字节,这样把整个区域来进行扫描,这样较少index.
在这里插入图片描述
写屏障来维护卡表
赋值之前成为写前屏障
赋值之后成为写后屏障

关于G1

G1垃圾收集器两个突出的改进。
(1) 基于标记整理算法,不产⽣内存碎⽚。
(2) 可以精确地控制停顿时间,在不牺牲吞吐量的前提下实现短停顿垃圾回收。

G1将 堆划分为多个大小相等的独立区域Region。
G1还是有 老年代和年轻代,只是逻辑上的概念,并且可以是不连续的了。
关于对大对象的处理,不再是大对象直接进入老年代,有一个单独分配大对象的Region区域叫做Humongous区。
超过Region区的百分之50,就会进入Humongous

阶段:

  1. 初始标记(initial mark,STW):cms初始标记
  2. 并发标记(concurrent Marking):cms并发标记
  3. 最终标记(Remark STW):cms重新标记
  4. 筛选回收(Cleanup STW):这个阶段会根据Region的回收价值和成本进行排序,根据用户所期望的停顿时间 (JVM参数:-xx:MAXGCPauseMills指定),尽量把GC导致的停顿时间控制在我们指定的范围内。

该算法主要是 复制算法,将一个region存活对象复制到另一个存活的对象中去。
cms会有内存碎片产生,还需要再清理一次。G1几乎没有内存碎片。

尽量把GC导致的停顿时间控制在我们指定的范围内?
主要G1在后台维护了一个优先列表,根据允许的收集时间,选择回收价值最大的Region。一个region花费200ms回收10m垃圾,另一个回收50ms。有限选择50ms的回收。

G1收集器:
YoungGC: 不是eden区域放满了就会马上出发,而是计算现在的回收时间,如果远远小于设置的停顿时间,就会增加eden region区域。接近参数的时候,才会出发YoungGC.
MixedGC:不是FullGC,老年代的堆占有率达到参数(-XX:InitiatingHeapOccupancyPercent)设定的值则触发,回收所有的Young和部分Old(根据期望的GC停顿时间确定old区垃圾收集的优先顺序)以及大对象区,正常情况G1的垃圾收集是先做MixedGC,主要使用复制算法,需要把各个region中存活的对象拷贝到别的region里去,拷贝过程中如果发现没有足够的空region能够承载拷贝对象就会触发一次Full GC。
FullGC:停止系统程序,然后采用单线程进行标记、清理和压缩整理,好空闲出来一批Region来供下一次MixedGC使用,这个过程是非常耗时的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值