JVM的经典垃圾收集器( 二 )


七.CMS收集器(重点) 7.1概述
CMS( Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器 。目前很大一部分的Java应用集中在互联网网站或者基于浏览器的B/S系统的服务端上,这类应用通常都会较为关注服务的响应速度,希望系统停顿时间尽可能短,以给用户带来良好的交互体验 。CMS收集器就非常符合这类应用的需求 。
7.2四个步骤
从名字(包含“Mark Sweep”)上就可以看出CMS收集器是基于标记-清除算法实现的,它的运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为四个步骤,包括:
1)初始标记(CMSmark)
STW,初始标记仅仅只是标记一下能直接关联到的对象,速度很快
2)并发标记(CMSmark)
并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行
3)重新标记(CMS )
重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(详见3.4.6节中关于增量更新的讲解),这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短
4)并发清除(CMSsweep)
清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的
由于在整个过程中耗时最长的并发标记和并发清除阶段中,垃圾收集器线程都可以与用户线程一起工作,所以从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的 。通过图3-11可以比较清楚地看到CMS收集器的运作步骤中并发和需要停顿的阶段 。
7.3优点
并发收集、低停顿
7.4缺点
①CMS收集器对处理器资源非常敏感
并发阶段,它虽然不会导致用户线程停顿,但却会因为占用了一部分线程(或者说处理器的计算能力)而导致应用程序变慢,降低总吞吐量
②CMS收集器无法处理“浮动垃圾”( )
在CMS的并发标记和并发清理阶段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们,只好留待下一次垃圾收集时再清理掉 。这一部分垃圾就称为“浮动垃圾” 。
同样也是由于在垃圾收集阶段用户线程还需要持续运行,那就还需要预留足够内存空间提供给用户线程使用,因此CMS收集器不能像其他收集器那样等待到老年代几乎完全被填满了再进行收集,必须预留一部分空间供并发收集时的程序运作使用 。
③CMS是一款基于“标记-清除”算法实现的收集器,可能产生大量空间碎片
八. First收集器(重点) 8.1概述
First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于的内存布局形式 。
虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(),每一个都可以根据需要,扮演新生代的Eden空间、空间,或者老年代空间 。
中还有一类特殊的区域,专门用来存储大对象 。G1认为只要大小超过了一个容量一半的对象即可判定为大对象 。每个的大小可以通过参数-XX:设定,取值范围为1MB~32MB,且应为2的N次幂 。而对于那些超过了整个容量的超级大对象,将会被存放在N个连续的 之中,G1的大多数行为都把 作为老年代的一部分来进行看待,如图3-12所示 。