ICode9

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

JVM之CMS垃圾回收器

2021-02-18 13:34:33  阅读:199  来源: 互联网

标签:黑色 标记 对象 白色 垃圾 JVM CMS 节点 引用


第一款真正意义上的并发垃圾回收器Concurrent Mark Sweep并发标记清除垃圾回收器

垃圾回收的主要流程为以下

1.初始标记:发生STW,初始标记阶段仅仅是标记一下GC roots能够直接引用的对象,就恢复用户线程的执行,因此暂停时间很短。

2.并发标记:并发标记就是从初始标记过的那些对象出发,遍历整个对象图的过程。

由于用户线程和标记线程一块执行,所以并发标记中存在一些问题:

  • 多标:原本是在对象整个引用链中的,在标记过后引用断开了,变成了垃圾对象,这种属于浮动垃圾,本次垃圾回收无法清理。
  • 漏标:CMS使用的是三色标记法(没了解过的同学需要去了解一下),使得原本应该标记为黑色的对象,被标记成了白色。
    原本标记为黑色的对象被标记为了白色必须同时满足下面两个条件
    (1) 赋值器插入了一条或多条从黑色对象到白色对象的引用。(因为黑色对象一般来说不会再进行遍历,所以白色对象的状态不会该表)
    (2)赋值器删除了所有从灰色对象到该白色对象的引用。(所有白色对象都是经由灰色对象遍历到从而变灰再变黑)

3.重新标记

重新标记索要做的工作就是修复在并发标记中引用发生的修改,该部分也是STW的,不然如果引用一直修改的话,重新标记将会一直无法结束。

CMS采用的是 写屏蔽+ 增量更新完成漏标的问题

假设现在有黑色节点 A ,灰色节点B 白色节点C

A -->> B -->> C
在这里插入图片描述

此时引用发生改变了 A–>>B并且 A–>>C
在这里插入图片描述

漏标的代码如下

Obj var = B.fieldC;
B.fieldC = null;
A.fieldC = var;

写屏障+增量更新
写屏障+增量更新的思路就是破坏第一个条件:黑色节点插入了白色节点的引用。当黑色节点插入了白色节点的引用时,即A.fieldC = var;我们记录下当前黑色节点,在重新标记的阶段将该节点再次进行遍历。(实际上相当于插入白色结点之后将黑色节点变为灰色节点)

写屏障+SATB (Snapshot at the begin)

写屏障+原始快照的思路是破坏第二个条件:当灰色节点删除了对应白色节点的引用B.fieldC = null;,将该白色节点的引用加入到待遍历的集合中,即以一开始的对象图的来进行遍历。这样可能会产生多标的问题,下次进行垃圾回收再进行收集即可。

4.并发清除

并发清除阶段的问题:

1.黑色对象变为白色对象

当我们进行并发清除的时候,如果黑色对象所有指向它的引用都被清除了,那么他就变成了浮动垃圾,本次垃圾回收并不会对他进行清除。

2.白色对象变为黑色对象(不可能)

这种情况明显不可能,白色对象只能通过灰色对象可达,但是上述三个阶段完成之后,对象只剩下白色和黑色对象,所以无法将任何一个白色对象的引用重新接上黑色对象。

3.新对象会不会被误删除?

新对象创建肯定没有被标记为黑色,为什么新对象不会被删除呢?因为在垃圾回收阶段,新对象会被分配到空闲列表的指定区域,gc不会对这片区域进行回收。

5.CMS存在的问题

浮动垃圾,所以CMS不能到内存彻底不够用时才进行回收,需要提前进行回收以达到有内存缓冲的目的。

标签:黑色,标记,对象,白色,垃圾,JVM,CMS,节点,引用
来源: https://blog.csdn.net/shangshanzixu/article/details/113844959

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

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

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

ICode9版权所有