JVM垃圾收集器介绍(一)


JVM垃圾收集器器主要有serial、parallel scavenge、parNew、CMS、G1、zgc、shenandoah等垃圾收集器,本次主要介绍serial、parallel scavenge、parNew、CMS垃圾收集器。
在介绍垃圾收集器之前先介绍下垃圾收集的算法

一、垃圾收集算法

1、标记复制法

标记复制法即是将内存分为相同的两块,每次使用其中的一块,当使用的内存完后,标记内存中存活对象,并将其复制到对应的另一块内存中,此算法效率很高,适用在年轻代中使用。
在这里插入图片描述
在这里插入图片描述

2、标记清理法

标记清理法其算法主要是对内存中的存活对象(或垃圾对象)进行标记,然后将垃圾对象内存清理掉,保留存活对象。此算法可能会出现:若对象很多,会出现效率问题,二是出现很多不连续的内存碎片,主要用于老年代。
在这里插入图片描述
在这里插入图片描述

3、标记整理法

标记整理算法可以理解为标记清理算法的一次优化,标记过程是一致,但是清理时是将存活对象向一块移动,使之存活对象和可用内存分离开来,主要用于老年代。
在这里插入图片描述
在这里插入图片描述

二、垃圾收集器

1、serial

serial是最久远的一款hotspot虚拟机的垃圾收集器,它是串行的垃圾收集器,即是单线程的,年轻代采用标记复制法,老年代采用标记整理法,在进行垃圾收集时会发生STW(stop the world)暂停所有线程直到清理结束。其劣势就是会STW出现应用线程停顿,用户体验相对差一些,其优势就是相比其他的单线程的效率高。
在这里插入图片描述使用serial垃圾收集器的参数为:-XX:+UseSerialGC -XX:+UseSerialOldGC
其中serialOld是针对老年代的垃圾收集器,目前主要用途为是作为CMS垃圾收集器的备用项。

2、Parallel Scavenge

Parallel scavenge垃圾收集器可以看成是serial垃圾收集器的并行版本即多线程版本,线程个数与cpu核数基本一致,但也可以通过参数(-XX:ParallelGCThreads)
来修改线程数,但建议使用默认的。
在这里插入图片描述Parallel scavenge分为年轻代和老年代版本-XX:+UseParallelGC(年轻代),-XX:+UseParallelOldGC(老年代),其中年轻代算法为标记复制法,老年代为标记整理法。此垃圾收集器是jdk8默认年轻代和老年代的垃圾收集器。

3、ParNew

parNew垃圾收集器跟parallel scavenge垃圾收集器很类似,其主要区别为可以配合CMS垃圾收集器进行年轻代和老年代的垃圾收集。
在这里插入图片描述ParNew其年轻代算法为标记复制法,老年代为标记整理法。-XX:+UseParNewGC(年轻代),-XX:+UseParNewOldGC(老年代)。

4、CMS

CMS(Concurrent Mark Sweep)垃圾收集器使用的算法是标记清理算法,其主要用于full GC垃圾收集,主要通过ParNew+CMS两种搭配来使用,CMS可以说是hotspot虚拟机的第一款真正意义上的并发的垃圾收集即:应用程序和垃圾程序同时进行,其主要缩短了STW的停顿时间,提高了用户的体验。其收集过程主要分为五步:
在这里插入图片描述1) 初始标记:即是先STW,暂停所有线程,然后通过可达性分析法GC root对直接引用的对象进行标记;
2) 并发标记:并发标记是gc线程与应用线程同时执行,在此阶段使用GC root进行对引用的所有对象进行标记,因此过程是并行,可能出现GC root标记的对象已经废弃(浮动垃圾)或在应用程序执行过程中产生新的对象GC root未来得及标记;
在这里插入图片描述3) 重新标记:此步骤会进行STW,暂停所有的线程,然后对上步并发标记进行修正及检验,将漏标的对象进行标记;
4) 并发清理:此步骤是应用程序和gc线程同时进行,在此步骤进行上面的标记后的垃圾清理工作,此步骤因为是并行,应用程序可能会废弃一些对象,此步骤产生的垃圾(浮动垃圾)会在下次垃圾回收进行清理;
5) 并发重置:重置此次GC的标记对象即将标记清除。
通过以上步骤会发现CMS垃圾收集器的主要优点为并发收集及低停顿,用户体验良好(虽然在初始标记和重新标记都会STW,但是对于前几款的STW的时间会大大缩短)
但是其也有几点缺点:
1) 因为垃圾收集器线程与应用程序并行执行,会出现争抢资源情况;
2) 会出现浮动垃圾即在第二步并发标记和第四步并发清理阶段出现,且浮动垃圾只能在下次gc处理;
3) 因垃圾收集器和应用程序并行执行,可能出现此次垃圾尚未收集完成,然后因应用程序的执行又会触发垃圾收集,可能出现在并发标记和并发清理阶段,若出现这种情况,会先进行STW,然后使用上面提到的serialOld垃圾收集器进行收集;
4) 提到此垃圾收集器的算法是标记清理,故会出现内存碎片的情况,但可以通过参数-XX:+UseCMSCompactAtFullCollection可以让jvm在执行完标记清除后再做整理来进行解决。
涉及CMS用到的主要参数有:
1) -XX:+UseConcMarkSweepGC:启用cms;
2) -XX:ConcGCThreads:并发的GC线程数;
3) -XX:+CMSParallellnitialMarkEnabled:初始标记阶段多线程执行;
4) -XX:+CMSParallelRemarkEnabled:重新标记的阶段多线程执行;
5) -XX:+UseCMSCompactAtFullCollection:解决内存碎片,在fullgc后做内存整理;
6) -XX:CMSInitiatingOccupancyFraction: 老年代使用达到该比例时会触发FullGC(默认是92,这是百分比);
7) -XX:+CMSScavengeBeforeRemark:在full gc前启动一次minor gc。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值