JVM-CMS全过程分析

其实网上有很多这类的文章,但是主要最近闲来无事,就写一下自己在经过了各类书籍的研究后得出的一些自己的见解。

那么CMS的大部分流程其实都有说到,那么我们就从每个细节开始讲解一下吧。

1.初始标记
2.并发标记
3.重新标记
4.并发清除

一.首先是第一步:初始标记,该过程会导致STW,这个过程是为了扫描JVM当中的根对象(GC roots)以及直接关联的对象,所谓的根对象一般来说的话通常是指(1)栈中所使用到的对象。(2)本地方法所使用到的对象。(例如native)。(3)Class对象。(4)静态+final变量。(5)synchronized锁定的对象。等等(可以参考的文章)https://blog.csdn.net/xhh198781/article/details/42213847

那么这个时候扫描的时候就有两种方式,(1)广度优先(2)深度优先。那么CMS选择的是深度优先,这样的好处比较明显,因为计算机有一个预读机制,那么这个时候深度优先就会比广度优先更有效率。那么找到之后需要如何标记喃?

这个时候就会出现一种标记方法,三色标记法(黑白灰)。刚开始扫描一个对象的时候会先把它标记为灰色,然后去遍历其引用

(1)没有子节点引用了,那么会把他变为黑色。

(2)遍历其引用,首先将他变为黑色,然后将子节点引用变为灰色,接着遍历引用。(当然,该步骤不会只会去找GC Root对象,而不会去寻找其他对象)

那么JVM是如何处理颜色喃?

(1)黑:遍历完毕,不是垃圾

(2)灰:正在遍历

(3)白:垃圾,未扫描到的。

那么初始标记只会有两种颜色,黑色和灰色。那么这个时候第一步就走完了。

二.并发标记。

就是并发标记第一步标记的对象,把目前存活的对象标记上黑色。

由于叫做并发标记,那么何谓并发?

就是指GC线程和用户线程一起运行。那么中间就有可能出现对象关系发生改变的情况了。那么我们举个例子

下图最开始的关系是 A -> B -> C(A拥有B的引用,B拥有C的引用)。

那么在第二步刚好扫描到B的时候,用户线程将关系变成了A ->C ,B变成无引用。

那么这个时候C就可能在系统中找不到了,因为A已经是黑色了,不会再根据A去搜索了。

所以这个时候CMS提供了一种write barrier

write barrier是指记录当时引用的变化情况。

当整个环境中不存在灰色的时候就是重新标记的时候了。

三.重新标记

所谓的重新标记是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。那么是如何修正的喃?CMS是利用写屏障来保证,所谓的写屏障可以理解为在有对象关系变更的时候(除去删除)会加一层AOP处理,会将对象变化记录下来,但是新的线程产生的是没法记录下来的,那么就需要STW,然后通过日志进行对象关系变更,再次标记。

四.并发清除

并发清除是GC线程和用户线程一起执行的,那么这个时候新生成的对象是不会在这次GC范围之中的,那么就会有浮动垃圾。

那么只会处理在这次GC中被标记(为白色)的了。并且一旦经过了重新标记之后,仍然是白色的对象就不会被引用了。

如果只是标记清除即可,如果发生整理,和将年轻代移动到老年代的时候,就需要涉及到修改指针的问题了,

(1)直接引用:

那么流程大概是将所有引用到该对象的对象的地址变更。

(2)句柄:

那么直接将句柄中的值改掉即可,那么所有引用都会改变了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值