如果想使用concurrent GC,系统默认是ParNew处理新生代垃圾,CMS处理老年代垃圾,下面是这两个收集器的详细介绍
从线程的角度分析
ParNew
ParNew概念
ParNew收集器是用于新生代的并行多线程垃圾收集器,采用“复制”算法。它是Serial收集器的多线程版本,使用多条线程进行垃圾收集。ParNew收集器除了采用并行回收的方式回收内存外,两款垃圾收集器之间几乎没有任何区别。在年轻代中,由于回收次数频繁,使用并行的方式可以更高效地完成工作。
此外,ParNew收集器是许多JVM运行在Server模式下新生代的默认垃圾收集器。开发人员可以通过选项-XX:+UseParNewGC手动指定使用ParNew收集器执行内存回收任务。XX:ParallelGCThreads可以限制线程数量,默认开启和CPU数据相同地线程数。
ParNew优势
-
并行处理:ParNew收集器利用多个线程并行地执行垃圾收集操作,可以充分利用多核处理器的优势,提高垃圾收集的效率。
-
低停顿时间:ParNew收集器采用分代收集的方式,可以减少每次垃圾收集的范围。同时,在收集过程中,通过与应用程序并发执行,最大程度地减少了应用程序的暂停时间。
-
与CMS配合使用:ParNew收集器通常与CMS(Concurrent Mark Sweep)收集器配合使用,用于处理新生代的垃圾收集。CMS收集器可以在应用程序执行过程中并发地执行垃圾收集,进一步减少了垃圾收集的停顿时间。
-
支持大内存堆:ParNew收集器可以有效地处理大内存堆,通过并行收集操作和分代收集策略,可以提高垃圾收集的效率,减少应用程序的停顿时间。
CMS
CSM概念
CMS(Concurrent Mark Sweep)垃圾回收器是一种并发式的垃圾回收器,主要用于老年代的垃圾回收。它主要设计目标是降低STW(Stop The World)的时间,通过并发执行来提高GC回收的效率。
以下是CMS垃圾回收器的几个关键特性:
并发处理:CMS主要的特点是它在回收过程中可以与应用程序并发运行,这意味着在GC运行时,应用程序不会被完全停止,从而降低了STW的时间。
标记清除:CMS使用标记-清除算法进行垃圾回收。这意味着在清除阶段,它会清除所有未标记的对象。这种方法的缺点是会产生大量的内存碎片,可能导致大对象无法找到连续的内存空间。
触发条件:CMS有一个触发垃圾回收的阀值,即当老年代或永久代内存达到92%时开始进行垃圾回收。
三色标记:在并发标记阶段,由于标记期间与应用程序并行,对象间的引用关系可能发生变化,因此采用三色标记的方式对对象进行标记,标记过程分为三种颜色:白色、灰色、黑色。
空间整理:为了解决内存碎片问题,CMS在并发执行若干次Full GC之后,下一次Full GC会先进行碎片整理。但这种整理方法在JDK9之后已被废弃。
内存泄漏检测:虽然CMS不是专为检测内存泄漏而设计的,但它可以帮助开发者检测某些类型的内存泄漏。
适用场景:CMS主要适用于对响应时间要求高的场景,如在线应用等。
请注意,使用CMS垃圾回收器时需要注意其可能产生的内存碎片问题和大对象分配问题。
CMS执行过程
1)初始标记:初始标记的作用就是找到根上的对象,也叫root,这个过程是STW的
2)并发标记:业务线程继续,垃圾回收器也在工作,找哪些是垃圾并进行规则的标记,一定会产生错误标记的情况(比如一开始这个对象不是垃圾,后来标记的过程中变成了垃圾,反之亦然)
3)重新标记:修正的过程是就是为了修复并发标记中出现的错误标记,这个过程也是STW的,因为出错的对象标记不是特别多
4)并发清理:对未标记的对象执行并发清理
三色标记算法
该算法主要是用在并发标记阶段,还没有清理哈。因为线程的开始与结束都是由CPU去调度的,所以可能会存在标记到一半,并发标记的线程挂起,那么这个时候标记的数据(已经有一半的对象被标记)不能丢失,需要保存,等待下一次并发标记的时候,继续在这个基础上开始标记,最终完成并发清理的步骤
注意:标记的颜色是存放在对象的markWord中。
在JVM中,Mark Word是一个特殊的部分,主要用来存储线程锁的状态以及用于垃圾回收。此外,Mark Word还可能包含该对象的hashCode,以及指向该对象所属的类的指针。Mark Word中的信息对于JVM进行垃圾回收和线程同步是至关重要的。
三色标记中的三色
1、黑色
表示在扫描过程中,这个对象包括他的孩子对象也被找到了,被标记成黑色,那么下一次再次扫描的时候,就i不会再扫描黑色的对象了
2、灰色
本身的对象被扫描到这个对象被标记,但是他的孩子对象还没有被标记,这种对象会被标记成灰色。当我们垃圾回收线程暂停,重新回来扫描的时候,不会扫描这个对象,会直接去扫描它的孩子对象
3、白色
没有被扫描到的对象,被标记成白色
三色标记中出现的情况
1、B->D消失 A->D增加
首先B->D消失这个问题不是很大。如果此时D没有被扫描,会被认定为floating garbage浮动垃圾,如果再下次扫描的时候还是没有被扫描到,才会被清理
而 B->D消失与此同时A->D增加才是影响最大的。会导致什么问题呢?会导致第一次扫描A已经是黑色的了,所以第二次扫描不会扫描A对象的孩子对象,也就是说D对象不会被扫描到;另外本身B对象是可以在灰色状态下扫描到D对象的,但是由于业务代码的改变B无法指向到D了,那么这个时候D对象如果不进行修正标记,就会被当作垃圾对象被清理
CMS的解决方案就是:把A对象变成灰色!也就是说黑色对象在第二次扫描的时候,增加了新的孩子对象,那么这个时候需要将它的黑色变成灰色,进行跟踪,这样灰色的对象就会被扫描它的孩子对象,这样D对象就会被扫描到了~
CMS天生的BUG:
三色标记法无论如何都是会存在漏标的情况。详细的流程如下
至此,关于这一组非常经典的垃圾回收器以及著名的三色标记算法介绍完毕,后续还会持续更新,敬请期待~~~