For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
CMS收集器是大多数Java编程开发程序员会经常用到的一种垃圾收集器,而本文我们就通过案例分析来简单了解一下,CMS收集器包含哪些阶段。
为了尽量减少用户线程的停顿时间,CMS采用了一种全新的策略使得在垃圾回收过程中的某些阶段用户线程和垃圾回收线程可以一起工作,这样就避免了因为长时间的垃圾回收而使用户线程一直处于等待之中。
整个过程就像我们打扫房间的时候可以让大家留在房间里工作,等我把房间的其他地方都打扫完,只剩大家工作的那部分区域的垃圾,这个时候再让大家到房间外面去,我再把房间里那些剩下的地方清理干净就行了,这样做的好处就是大家的工作时间变长了,在房间外等待的时间变短了。
CMS也是按这个逻辑把整个垃圾收集的过程分成四个阶段,分别是初始标记、并发标记、重新标记、并发清理四个阶段,然后CMS会根据每个阶段不同的特性来决定是否停顿用户线程。
阶段一:初始标记
初始标记的目的是先把所有GCRoot直接引用的对象进行标记,因为需要避免在标记GCRoot的过程还有程序在继续产生GCRoot对象,所以这个过程是需要需要停止用户线程,因为这个过程只会标记GCRoot的直接引用,并不会对整个GCRoot的引用进行遍历,所以这个过程速度也是所有阶段中快的。
阶段二:并发标记
并发标记阶段的工作就是把阶段一标记好的GCRoot对象进行深度的遍历,找到所有与GCRoot关联的对象并进行标记,这个过程中是采用多线程的方式进行遍历标记,对整个JVM的GCRoot进行遍历的过程是垃圾收集过程中耗时的一步,CMS为了考虑尽量不停顿用户线程,所以这个阶段是不停止用户线程的,也就是说这个阶段JVM会分配一些资源给用户线程执行任务,通过这样的方式减少用户线程的停顿时间。
阶段三:重新标记
因为在阶段二的时候用户线程同时也在运行,这个过程中又会产生新的垃圾,所以重新标记阶段主要任务是把上一个阶段中产生的新垃圾进行标记(使用多线程标记),很显然这个过程是对上一个阶段用户线程运行遗留的垃圾进行标记,所以数量是非常少执行时间也是短的,当然为了避免这个过程再次产生新的垃圾,所以重新标记的过程是会停顿用户线程的。
阶段四:并发清理
并发清理阶段是对那些被标记为可回收的对象进行清理,在一般情况下并发清理阶段是使用的标记清除法,因为这个过程不会牵扯到对象的地址变更,所以CMS在并发清理阶段是不需要停止用户线程的。也正因为并发清理阶段用户线程也可以同时运行,所以在用户线程运行的过程中自然也会产生新的垃圾,这也就是导致CMS收集器会产生“浮动垃圾”的原因。
当然,在一种情况下并发清理阶段CMS也会停顿用户线程,这就和我们之前说过的CMS选用的垃圾回收算法有关系,因为一般情况下使用的都是标记清除法,但是标记清除法的弊端就是在于会产生空间碎片,所以当空间碎片到达了一定程度时,此时CMS会使用标记整理法解决空间碎片的问题,不过因为标记整理法会将对象的位置进行挪动并更新对象的引用的指向地址,那么这个过程中用户线程同时运行的话会产生并发问题,所以当CMS进行碎片整理的时候必须得停止用户线程。
CMS的特点
收集区域:老年代。
使用算法:标记清除法+标记整理法。
搜集方式:多线程。
搭配收集器:ParNew。
优势:多线程收集,收集过程不停止用户线程,所以用户请求停顿时间短。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei456学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。