目录
Serial收集器
基本概念:Serial收集器是最基本、发展历史最久的收集器,这个收集器是采用复制算法的单线程的收集器。
重点:其采用复制算法和单线程。
单线程的收集器:
- 单线程一方面意味着他只会使用一个 CPU 或者一条线程去完成垃圾收集工作;
- 另一方面也意味着他进行垃圾收集时必须暂停其他线程的所有工作,直到它收集结束为止。
这就造成了很大的STW(stop the world) 只有垃圾回收线程工作,其他线程停止,世界好像静止一般。
不过实际上到目前为止,Serial收集器依然是虚拟机运行在 Client 模式下的默认新生代收集器,因为它简单而高效。Serial 收集器运行过程如下图所示。
Parnew收集器
基本概念:Parnew 收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为和 Serial 收集器完全一样,但是他却是 Server 模式下的虚拟机首选的新生代收集器。
- 除了 Serial 收集器外,目前只有它能与 CMS 收集器配合工作。CMS 收集器第一次实现了让垃圾收集器与用户线程基本上同时工作;
- Parnew 收集器默认开启的收集线程数与 CPU 数量相同,在 CPU 数量非常多的情况下,可以使用
-XX:ParallelGCThreads
参数来限制垃圾收集的线程数。
Parallel Scavenge
基本概念:Parallel Scavenge 收集器也是一个新生代收集器,也采用了复制算法,也是并行的多线程收集器。Parallel Scavenge 收集器的目标是达到一个可控制的吞吐量。Parallel Scavenge 收集器是虚拟机运行在 Server 模式下的默认垃圾收集器。被称为“吞吐量优先收集器”。
Tips:从概念上来看,我们需要注意Parallel Scavenge收集器的三个个特点:一个是采用复制算法,一个是多线程收集,一个是达到控制吞吐量的目标。
控制吞吐量:CMS 等收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间,而 Parallel Scavenge 收集器的目标则是达到一个可控制的吞吐量。所谓吞吐量就是 CPU 用于运行用户代码时间与 CPU 总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
。
空间吞吐量参数介绍:虚拟机提供了-XX:MaxGCPauseMills
和 -XX:GCTimeRatio
两个参数来精确控制最大垃圾收集停顿时间和吞吐量大小。不过不要以为前者越小越好,GC 停顿时间的缩短是以牺牲吞吐量和新生代空间换取的。由于与吞吐量关系密切,Parallel Scavenge 收集器也被称为“吞吐量优先收集器”。
CMS收集器
基本概念:CMS(Conrrurent Mark Sweep,连续标记扫描)收集器是以获取最短回收停顿时间为目标的收集器。使用标记-清除算法
收集步骤:收集过程分为如下四步:
- 初始标记:标记 GCRoots 能直接关联到的对象,时间很短--会产生STW;
- 并发标记:进行 GCRoots Tracing(可达性分析)过程,时间很长;
- 重新标记:修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,时间较长--会产生STW;
- 并发清除:回收内存空间,时间很长。其中,并发标记与并发清除两个阶段耗时最长,但是可以与用户线程并发执行。
CMS 收集器运行过程如下图所示:
从上面的描述步骤中我们可以看出:CMS 之所以能极大地降低 GC 停顿时间,本质上是将原本冗长的引用链扫描进行切分。通过 GC 线程与用户线程并发执行,加上重新标记校正的方式,减少了垃圾回收的时间。
缺点
对 CPU 资源消耗较大:例如只有 2 个 CPU 时,垃圾回收线程占用就达到了 50%,也就是说需要拿 50% 的 CPU 时间来进行垃圾回收。这就会极大地降低系统的吞吐量
无法处理浮动垃圾:由于 CMS 并发标记阶段会发生漏标的情况,因此会有一些本该回收的垃圾对象无法被回收。此外,在 CMS 进行并发清理的时候,用户线程同时在运行,也会产生一些浮动垃圾。因此对于 CMS 回收器来说,其需要留出一些空间给这些浮动垃圾存储
产生空间碎片:由于 CMS 是基于「标记-清除」算法实现的回收器,因此其会产生很多空间碎片
G1收集器
基本概念:G1 是目前技术发展的最前沿成果之一,HotSpot开发团队赋予它的使命是未来可以替换掉 JDK1.5 中发布的 CMS 收集器。
与其他GC收集器相比,G1收集器具有以下特点:
- 并发和并行:使用多个 CPU 来缩短 Stop The World 停顿时间,与用户线程并发执行;
- 分代收集:独立管理整个堆,但是能够采用不同的方式去处理新创建对象和已经存活了一段时间、熬过多次 GC 的旧对象,以获取更好的收集效果;
- 空间整合:基于标记-整理算法,无内存碎片产生;
- 可预测的停顿:能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集器上的时间不得超过N毫秒。
在G1之前的垃圾收集器,收集的范围都是整个新生代或者老年代,而 G1 不再是这样。使用 G1 收集器时,Java 堆的内存布局与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分(可以不连续)Region 的集合。