七种垃圾收集器特点、优劣势、及使用场景

如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。

HotSpot JVM:
在这里插入图片描述
上面有7种收集器,分为两块,上面为新生代收集器,下面是老年代收集器。如果两个收集器之间存在连线,就说明它们可以搭配使用。

一、Serial(串行GC)收集器:

Serial 收集器是一个新生代收集器,单线程执行,使用复制算法。它在进行垃圾收集时,必须暂停其他所有的工作线程(用户线程)。
对于限定单个CPU的环境来说,由于没有线程交互的开销,可以获得最高的单线程收集效率。
在这里插入图片描述
Serial 收集器依然是虚拟机运行在 Client 模式下默认新生代收集器,对于运行在 Client 模式下的虚拟机来说是一个很好的选择。

二、ParNew(并行GC)收集器:

ParNew收集器是新生代并行收集器,其实就是serial收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数、收集算法、Stop The Worl、对象分配规则、回收策略等都与Serial 收集器完全一样。
在这里插入图片描述
在多核CPU上,回收效率会高于串行回收器;反之在单核CPU, 效率会不如串行回收器 。

ParNew收集器默认开启和CPU数目相同的线程数,可以通过-XX:ParallelGCThreads参数来限制垃圾收集器的线程数;

ParNew收集器是许多运行在Server模式下的虚拟机中首选新生代收集器,主要原因是,除Serial收集器之外,目前只有ParNew它能与CMS收集器配合工作。

三、Parallel Scavenge(并行回收GC)收集器:

1、Parallel Scavenge收集器也是一个新生代收集器,使用复制算法,并行多线程收集器。Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。(吞吐量= 程序运行时间/(程序运行时间 + 垃圾收集时间),虚拟机总共运行了100分钟。其中垃圾收集花掉1分钟,那吞吐量就是99%)。高吞吐量可以最高效率地利用CPU时间,尽快完成程序的运算任务,主要适用于在后台不需要太多交互的任务。

2、Parallel Scavenge收集器提供了两个参数用于精准控制吞吐量:

(1)-XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间,是一个大于0的毫秒数。

(2)-XX:GCTimeRation:直接设置吞吐量大小,是一个大于0小于100的整数,也就是程序运行时间占总时间的比率,默认值是99,即垃圾收集运行最大1%(1/(1+99))的垃圾收集时间。

3、支持自适应的GC调节策略。它还提供一个参数:-XX:+UseAdaptiveSizePolicy,这是个开关参数,打开之后就不需要手动指定新生代大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRation)、新生代晋升年老代对象年龄(-XX:PretenureSizeThreshold)等细节参数,虚拟机会根据当前系统运行情况收集性能监控信息,动态调整这些参数以达到最大吞吐量。

四、Serial Old(串行GC)收集器:

Serial Old是Serial收集器的老年代版本,它同样使用一个单线程执行收集,使用“标记-整理”算法。主要是运行在Client的Java虚拟机默认的老年代垃圾收集器。

通常老年代垃圾回收比新生代回收要更长时间,所以会使应用程序停顿较长时间。

主要用途:作为年老代中使用CMS收集器的后备垃圾收集方案。当CMS收集器产生Concurrent Mode Failure时,将临时启动Serial Old收集器重新进行老年代的垃圾收集。

五、Parallel Old(并行GC)收集器:

Parallel Old是Parallel Scavenge收集器的老年代版本,jdk1.6之后开始提供,使用多线程和“标记-整理”算法。

在JDK1.6之前,新生代使用Parallel Scavenge收集器只能搭配年老代的Serial Old收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old正是为了在年老代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代Parallel Scavenge和年老代Parallel Old收集器的搭配策略。

六、CMS(并发GC)收集器:

1、CMS(Concurrent Mark Sweep)收集器应用于老年代,实现真正意义上的并发垃圾收集器,是一种以获取最短回收停顿时间为目标的收集器。CMS收集器是使用多线程和“标记-清除”算法实现的,整个收集过程大致分为4个步骤:

(1)初始标记(CMS initial mark):需要停顿所有用户线程,初始标记仅仅是标记出GC ROOTS能直接关联到的对象,速度很快。

(2)并发标记(CMS concurrenr mark):进行GC ROOTS 根搜索算法阶段,会判定对象是否存活,和用户线程一起工作,不需要暂停工作线程。

(3)重新标记(CMS remark):为了修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。需要停顿所有用户线程,停顿时间会被初始标记阶段稍长,但比并发标记阶段要短。

(4)并发清除(CMS concurrent sweep):清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。

 整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,所以整体来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。

2、CMS收集器工作过程:
在这里插入图片描述

3、优缺点:
CMS收集器的优点:并发收集、低停顿。

但是CMS还远远达不到完美,主要有四个显著缺点:

(1)CMS收集器对CPU资源非常敏感。在并发阶段,虽然不会导致用户线程停顿,但是会占用CPU资源而导致引用程序变慢,总吞吐量下降。CMS默认启动的回收线程数是:(CPU数量+3) / 4。

(2)CMS收集器无法处理浮动垃圾,可能出现“Concurrent Mode Failure“,失败后而导致另一次Full GC的产生。由于CMS并发清理阶段用户线程还在运行,伴随程序的运行自热会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在本次收集中处理它们,只好留待下一次GC时将其清理掉。这一部分垃圾称为“浮动垃圾”。

(3)由于在垃圾收集阶段用户线程还需要运行,即需要预留足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分内存空间提供并发收集时的程序运作使用。在默认设置下,CMS收集器在老年代使用了68%的空间时就会被激活,也可以通过参数-XX:CMSInitiatingOccupancyFraction的值来提供触发百分比,以降低内存回收次数提高性能。要是CMS运行期间预留的内存无法满足程序其他线程需要,就会出现“Concurrent Mode Failure”失败,这时候虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置的过高将会很容易导致“Concurrent Mode Failure”失败,性能反而降低。

(4)CMS是基于“标记-清除”算法实现的收集器,会产生大量不连续的内存碎片。空间碎片太多时,如果无法找到一块足够大的连续内存存放对象时,将不得不提前触发一次Full GC。为了解决这个问题,CMS收集器提供了一个-XX:UseCMSCompactAtFullCollection开关参数,用于在Full GC之后增加一个碎片整理过程,还可通过-XX:CMSFullGCBeforeCompaction参数设置执行多少次不压缩的Full GC之后,跟着来一次碎片整理过程。

七、G1收集器:

1、G1(Garbage First)收集器是JDK1.7提供的一个新收集器,与CMS收集器相比,最突出的改进是:

(1)基于“标记-整理”算法实现,不会产生内存碎片。

(2)可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。

G1收集器并不采用新生代和老年代物理隔离的传统布局方式(仅在逻辑上划分新生代和老年代),而是将整个堆内存划分为2048个大小相同的独立Region块,每个Region块的大小根据堆的实际大小而定,整体被控制在1M-32M之间。G1收集器跟踪Region中的垃圾堆积情况,并在后台维护一个优先级列表,每次根据设置的垃圾回收时间,回收优先级最高的区域,这样可以避免整个新生代或整个老年代的垃圾回收,使得stop the world的时间更短、更可控,同时在有限的时间内可以获得最高的回收效率。区域划分和优先级区域回收机制,确保G1收集器可以在有限时间获得最高的垃圾收集效率。

2、其他特点:

(1)并行性: 回收期间, 可由多个线程同时工作, 有效利用多核cpu资源;并发性: 与应用程序可交替执行, 部分工作可以和应用程序同时执行,

(2)分代GC: 分代收集器, 同时兼顾年轻代和老年代。他能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过了多次GC的对象,以便获取更好的GC效果。

3、G1的收集过程 :
在这里插入图片描述
G1收集器的阶段分以下几个步骤:

  1. 初始标记(它标记了从GC Root开始直接可达的对象)

  2. 并发标记(从GC Roots开始对堆中对象进行可达性分析,找出存活对象)

  3. 最终标记(标记那些在并发标记阶段发生变化的对象,将被回收)

  4. 筛选回收(首先对各个Regin的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region)

G1收集器的优势:

  • 独特的分代垃圾回收器,分代GC: 分代收集器, 同时兼顾年轻代和老年代
  • 使用分区算法, 不要求eden, 年轻代或老年代的空间都连续
  • 并行性: 回收期间, 可由多个线程同时工作, 有效利用多核cpu资源
  • 空间整理: 回收过程中, 会进行适当对象移动, 减少空间碎片
  • 可预见性: G1可选取部分区域进行回收, 可以缩小回收范围, 减少全局停顿

补充:Client、Server模式下默认的GC:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值