1 垃圾回收器
垃圾回收算法是JVM内存回收过程中具体的、通用的方法,垃圾收集器是JVM内存回收过程中具体的执行者,即各种GC算法的具体实现。
1.1 Serial
Serial 是最基础、历史最悠久的收集器。是一个单线程工作的收集器。在进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束。
1.2 ParNew
ParNew收集器其实就是Serial收集器的多线程版本。**新生代并行,老年代串行;**新生代复制算法、老年代标记-压缩。
1.3 Parallel Scavenge
Parallel Scavenge收集器也是一款新生代收集器,同样是基于标记-复制算法实现的收集器,也是能够并行收集的多线程收集器。目标是达到一个可控制的吞吐量。所谓吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值。可以参数设置垃圾收集停顿时间和吞吐量大小
。
1.4 CMS
CMS(Concurrent Mark Sweep) 收集器是一种以获取最短回收停顿时间
为目标的收集器。
基于标记-清除算法实现的。整个过程分为四个步骤
- 初始标记(CMS initial mark)
- 并发标记(CMS concurrent mark)
- 重新标记(CMS remark)
- 并发清除(CMS concurrent sweep)
其中初始标记、重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。由于整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发地执行。
是一个老年代收集器。
优点:并发收集、低停顿。
缺点:并发阶段会降低吞吐量。无法处理在CMS的并发标记和并发清理阶段,用户线程产生的新垃圾对象(浮动垃圾)。产生空间碎片。
1.5 G1
G1垃圾收集器并非横空出世,早在JDK1.7的时候就已经存在了。随着后续的优化,终于在JDK1.9的时候被Oracle付以重任,替换CMS成为默认的垃圾收集器。
- G1 收集器是基于“标记-整理”算法实现的收集器,不会产生空间碎片。
- 可以非常精确
控制停顿时间
,即能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。 - G1 将整个Java 堆划分为多个大小固定的
独立区域
,并且跟踪这些区域里面的垃圾堆积程度,在后台维护一个优先列表,每次根据运行的收集时间,优先回收垃圾最多的区域
。 - 流程:初始标记 并发标记 最终标记、筛选回收。除了并发标记外,其余阶段也要完全暂停用户线程。
- 目标:延迟可控的情况下尽可能高的吞吐量。
- 适用场景
- 同时注重吞吐量(Throughput)和低延迟(Low latency),默认的暂停目标是 200 ms
- 超大堆内存,会将堆划分为多个大小相等的 Region
- 整体上是 标记+整理 算法,两个区域之间是 复制 算法
1.6 Stop The World
Java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集器之外)。Java中一种全局暂停现象,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。
Stop The World : 由虚拟机在后台自动发起和自动完成的,在用户不可知、不可控的情况下把用户的正常工作的线程全部停掉。