两款垃圾收集器-CMS&G1
CMS
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。
CMS是hotspot虚拟机第一款真正意义上的(基本上)实现GC工作线程和用户线程同时工作的垃圾收集器。CMS采用的垃圾收集算法是标记-清除算法。它的运作过程相比于前面几种垃圾收集器来说更加复杂一些。整个过程分为四个步骤:
- 初始标记:暂停其他所有线程,标记一下GCROOTS能够关联到的对象。这个阶段速度很快
- 并发标记:从GCROOTS开始对堆上的对象进行可达性分析,记录可达对象。这个阶段会同时开启用户线程和GC工作线程。但是不保证所有可达对象都会被记录,因为用户线程可能会更新对象之间的引用关系。
- 重新标记:这一阶段会暂停用户线程,修改上一阶段因为用户线程的运行而导致标记更改的那一部分对象的标记记录。这一阶段的暂停时间比初始标记阶段稍长,但是远比并发标记阶段时间短。
- 并发清除:用户线程和GC工作线程同时运行,GC线程对未标记的区域进行清理。
CMS的主要优点有:**并发收集,低停顿。**但是它也有明显的三个缺点:1.无法清理浮动垃圾。2.使用标记-清除算法,垃圾回收后会产生大量内存碎片。3.对CPU资源敏感。
G1收集器(唯一一款全区域的垃圾收集器)
一个region有可能属于Eden,Survivor或者Tenured内存区域。图中的E表示该region属于Eden内存区域,S表示属于Survivor内存区域,T表示属于Tenured内存区域。图中空白的表示未使用的内存空间。G1垃圾收集器还增加了一种新的内存区域,叫做Humongous内存区域,如图中的H块。这种内存区域主要用于存储对象-即大小超过一个region大小的50%的对象。
年轻代垃圾收集 在G1垃圾收集器中,年轻代的垃圾回收过程使用复制算法。把Eden区和Survivor区的对象复制到新的Survivor区域。
老年代垃收集 在老年代的垃圾收集过程中,G1收集器主要采用标记-整理算法。 对于老年代上的垃圾收集,G1垃圾收集器也分为4个阶段,基本跟CMS垃圾收集器一样,但略有不同:
- 初始标记:和CMS的初始标记阶段一样,需要暂停其他所有线程,也是标记一下GCROOTS能够关联到的所有对象,但是G1的初始标记阶段是个minorGC一同进行的。
- 并发标记:从GCROOTS开始对堆上的对象进行可达性分析,记录可达对象。这个阶段会同时开启用户线程和GC工作线程,但是不保证所有可达对象都会被记录,因为用户线程可能会更新对象之间的引用关系。这个阶段G1比CMS还多做了一件事,就是C1如果发现某块region的对象存活几率很低的话,G1就会将这个region内的对象回收。同时G1也会计算每个对象的存活率,为后续筛选回收阶段做准备。
- 最终标记:这一阶段会暂停用户线程,修改上一阶段因为用户线程的运行而导致标记更改的那一部分对象的标记记录。G1在这一阶段采用的算法和CMS不同,G1能够更快的标记可达对象。
- 筛选回收:在这个阶段,G1会挑选出存活率低的region进行回收。这一阶段是个minorGC同时进行的。
G1比CMS的另一个巨大优势是:G1可以预测停顿时间。
|