JVM垃圾回收(三)-7种垃圾收集器

概述

垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法)的具体实现,不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚拟机中的垃圾收集器。7种垃圾收集器如图所示。
图中表示7种作用于不同分代的收集器,如果两个收集器之间存在连线,说明可以搭配使用。横线上办部分为年轻代的垃圾收集器,下半部分为老年代的垃圾收集器。
JVM垃圾回收(三)-7种垃圾收集器

相关概念

STW机制

Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。

吞吐量

指的是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即
吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。
假设虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

并行和并发

  • 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
  • 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行。而垃圾收集程序运行在另一个CPU上。

Minor GC 和 Full GC

  • 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
  • 老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。

Serial收集器

收集器流程图如图所示
JVM垃圾回收(三)-7种垃圾收集器
特点:单线程的收集器,在工作时,必须暂停其他所有的工作线程,直至它收集结束。也是虚拟机默认的新生代收集器
优点:

  • 单线程执行,没有线程交互的开销,
  • 垃圾收集停顿在几百毫秒内,这一定程度上可以接受

缺点:STW问题(“Stop The World”)

ParNew收集器

ParNew收集器就是Serial收集器多线程的版本。 除了多线程外,其余的行为、特点和Serial收集器一样;
在Server模式下,ParNew收集器是一个非常重要的收集器,因为除Serial外,目前只有它能与CMS收集器配合工作;
但在单个或两个CPU环境中,不会比Serail收集器有更好的效果,因为存在线程交互开销。

设置参数

  • "-XX:+UseConcMarkSweepGC":指定使用CMS后,会默认使用ParNew作为新生代收集器;
  • "-XX:+UseParNewGC":强制指定使用ParNew;
  • "-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;

parallel scavenger收集器

parallel scavenger收集器是达到一个可控制吞吐量。既尽量的缩短垃圾收集时间,保证与用户的交互速度。既给定一个指定的垃圾收集停顿收集,当垃圾收集时间超过给定值,无论是否回收完成都会停止回收工作。
特点:

  • 新生代收集器
  • 与ParNew一样 并行的多线程收集器
    设置参数
  • -XX:MaxGCPauseMillis
    控制最大垃圾收集停顿时间,大于0的毫秒数
    MaxGCPauseMillis设置得稍小,停顿时间可能会缩短,但也可能会使得吞吐量下降。因为可能导致垃圾收集发生得更频繁
  • -XX:GCTimeRatio
    设置垃圾收集时间占总时间的比率,0<n<100的整数
    GCTimeRatio相当于设置吞吐量大小
  • -XX:+UseAdptiveSizePolicy
    这是一个开关参数,打开参数后,就不需要手工指定新生代的大小(-Xmn)、Eden和Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种方式称为GC自适应的调节策略(GC Ergonomics)。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。

Serial Old收集器

Serial Old 是 Serial收集器的老年代版本,它同样是一个单线程收集器,使用 “标记-整理”(Mark-Compact) 算法。
此收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,它还有两大用途:

  • 在JDK1.5 以及之前版本(Parallel Old诞生以前)中与Parallel Scavenge收集器搭配使用
  • 作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用

Parallel Old收集器

Parallel Old收集器是parallel scavenger收集器的老年代版本。
特点:

  • 采用“标记-整理”算法
  • 多线程执行
  • Parallel Old收集器的工作流程与Parallel Scavenge相同

CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。

G1收集器

阉割 后续补充

相关推荐