简单了解JVM中的垃圾回收器

mac2024-10-13  62

单线程回收器

单线程回收器是指只开启一个线程进行垃圾回收的操作,进行垃圾回收时,暂停用户工作线程。在单CPU环境下,单线程回收器没有线程切换的开销,专心垃圾收集,更加简单高效。

1、Serial

新生代使用,采用复制算法

2、Serial Old

老年代使用,采用标记整理算法

Serial一般与Serial Old搭配使用

多线程回收器

顾名思义,多线程回收器通过多线程来进行垃圾回收。进行垃圾回收时,暂停用户工作线程。

1、ParNew

Serial的多线程版本,新生代使用,采用复制算法

2、Parallel Scavenge

新生代使用,采用复制算法。该算法关注吞吐量,如果设置了吞吐量的值,会动态调整新生代、eden区和survivor区的大小,使其尽可能达到设置的吞吐量。

-XX:MaxGCPauseMillis:设置最大停顿时间;

-XX:GCTimeRatio:设置吞吐量大小n,取值范围,公式1/(1+n)结果为垃圾回收时间与总时间(垃圾回收+用户线程)的比值。

3、Parallel Old

老年代使用,采用标记整理算法

4、CMS

老年代使用,采用标记清除算法。该算法关注垃圾回收过程中暂停所有工作线程的时间(越短越好)。进行垃圾清理时,用户工作线程同时运行。

 初始标记:暂停用户工作线程,标记GC Roots对象和GC Roots直接引用的对象,理论上来说需要标记对象比较少,速度很快;

并发标记:向下搜索,标记GC Roots直接引用对象引用的对象,这个过程可以与用户线程并发执行,耗时较长,但是用户无感知;

重新标记:并发标记过程中存在用户线程的执行,会产生新的GC Roots对象或GC Roots引用对象,需要将它们也标记起来,速度较快;

并发清理:清除没有标记的对象,回收内存空间;

重置:垃圾回收器内部数据结构重置。

注意:并发过程中产生的浮动垃圾需要再下一次垃圾回收中才能被清理,当CMS因为浮动垃圾过多导致出现异常时,JDK会使用默认的Serial Old垃圾回收器执行一次Full GC。

G1

新生代/老年代使用,内存上没有明确的新生代、老年代界限,采用标记整理算法。进行垃圾回收时,用户工作线程可同时运行。

G1分区: 

存在一个巨型对象(Humongous),存放占内存较大的对象。

过程与CMS有相似之处,但是存在整理过程,不会产生内存碎片。

图解:

算法的搭配

一般来说,按照下面所示搭配使用

 

 

如果有写的不对的地方,请大家多多批评指正,非常感谢!

最新回复(0)