ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CMS垃圾收集器总结

2022-08-15 03:02:21  阅读:189  来源: 互联网

标签:收集器 对象 标记 并发 GC 引用 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的线程计算公式:

  • -XX:ParallelGCThreads=m // STW暂停时使用的GC线程数,一般用满CPU
  • -XX:ConcGCThreads=n // GC线程和业务线程并发执行时使用的GC线程数,一般较小

      

 

  

 

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有