其他分享
首页 > 其他分享> > CMS垃圾收集器总结

CMS垃圾收集器总结

作者:互联网

CMS:

1.  初始标记    CMS initial mark:                 标记GC Roots 直接关联对象,不用Tracing,速度很快

2.  并发标记    CMS concurrent mark            进行GC Roots Tracing      不用STW  (和用户线程并行)

3.  重新标记     CMS remark                          修改并发标记因用户程序变动的内容

4.  并发清除      CMS concurrent sweep        清除不可达对象回收空间,同时有新垃圾产生,留着下次清理。

 

其中 初始标记在很多内容上都是 一个线程,那会不会多个线程呢,JDK8就可以,默认开启 -XX:+CMSParallelInitialMarkEnabled。

 

新生代:

CMS要进行老年代的垃圾回收,如何判断被年轻代引用的老年代对象是可达的呢?

  要扫描新生代,但是全量扫描特别慢,因此就需要先进行新生代的垃圾回收,然后再进行老年代的垃圾回收。

因此有两个参数:

  CMS提供CMSScavengeBeforeRemark参数,使remark前强制进行一次Minor GC

 

再说下老年代:

  新生代GC的时候,如果有老年代对象引用了我们新生代对象,老年代对象也应该加入gc roots范围中,如果每次进行young gc我们都需要扫描一次老年代的话,那代价太大了。  因此需要引入一种叫记忆集的首相数据结构来记录这种引用关系。

  记忆集是针对跨代引用提出来的,卡表是其具体体现。  使用卡表和写屏障来进行标记并加快对GC Roots的扫描

  通常讲堆空间划分为一系列2次幂大小的卡页。  卡表用于标记卡页的状态,每个卡表对应一个卡页,hotSpot 使用的卡页是512字节

  一个卡页中可包括多个对象,只要有一个对象的字段存在跨代指针,其对应的卡表元素标识就变成1,表示该元素变脏。只要GC时筛选收集区中变脏的元素加入GC Roots里。

  那么卡表元素如何维护呢? 何时变脏、谁来变脏?

  何时变脏很明显,年轻代引用了老年代元素就应该变脏,原则上应该发生再引用类型字段赋值的那一刻。

  那如何在对象赋值的那一刻去更新维护卡表呢?通过写屏障来维护卡表状态的。 

 

Foregroud CMS 是并发失败才会走的模式。

  那么什么是并发失败呢?

  并发收集器不能在年老代填满之前完成不可达对象的回收,或者老年代中有效空闲内存空间不能满足内存分配请求,此时会STW。

  也就是说,我在并发清除呢,内存不够了,此时会进行 serial old GC。

  为避免发生,可以通过设置XX:CMSInitiatingOccupancyFraction参数,去控制内存占用达到多少才开启并发收集器开始回收老年代。

 

  那么CMS采用标记清除算法,会导致内存碎片问题,因此会经常进行full GC 导致。  退化成full GC之后会有两个参数

  -XX:+UseCMSCompactAtFullCollection

  -XX:CMSFullGCsBeforeCompaction=0

  这两个参数表示多少次FullGC后采用MSC算法压缩堆内存,0表示每次FullGC后都会压缩,同时0也是默认值。

 

  三色标记:

  并发标记过程中,标记期间应用线程还在继续跑,对象间的引用可能发生变化,因此采用三色标记法。

  黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色对象代表已经扫描过,

  灰色:    已经被垃圾收集器访问过,这个对象上至少存在一个引用没被扫描

  白色:    尚未被垃圾收集器访问过。

  

  具体的流程:

  1.  初始时,所有对象都在白色集合中

  2.  将GC Roots 直接引用的对象挪到灰色集合中

  3.  从灰色集合中获取对象:

  4. 将本对象引用到的其他对象全部挪到灰色集合中

  5. 将本对象挪到黑色集合里面

  重复3,4,5 直至灰色集合为空。

  结束后,仍在白色集合的对象,即为GC Roots 不可达,可以回收。

 

  漏标情况。满足两种情况

  1. 灰色对象,断开了白色对象的引用,

  2.  黑色对象,重新引用了该白色对象。

  解决方案:

  1.  增量更新:

    黑色对象插入新的指向白色对象引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象重新扫描一次。 

  2.. 原始快照:

    灰色删除引用关系时,将要删除的引用记录下来,并发扫描扫描结束后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次,将白色标记为黑色。  

  无论是引用关系的插入还是删除。

  虚拟机的记录操作都是通过写屏障记录下来的。

     

  CMS的线程计算公式:

      

 

  

 

标签:收集器,对象,标记,并发,GC,引用,CMS,垃圾
来源: https://www.cnblogs.com/followers/p/16586734.html