接上篇,如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.
「Serial」(串行)收集器是最基本、历史最悠久的垃圾收集器了.通过名称就可以看出该垃圾收集器是一个单线程收集器了.
它的单线程的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作, 更重要的是它在进行垃圾收集工作 时候必须暂停其它所有的线程「Stop the world」, 直到它收集结束.
新生代采用复制算法, 老年代采用标记-整理算法
虚拟机的设计者当然知道对于「Stop the World」带来的不良用户体验, 所以在后续的垃圾回收器的设计中暂停时间被不断的缩短(但是仍然有停顿,寻找最优秀的垃圾收集器的过程还在继续)
「Serial」收集的器的优点在于简单而高效(相比与其它收集器的单线程).「Serial」由于没有与其它线程交互的开销,自然可以获得很高的单线程收集率.「Serial」收集器对于运行在Client模式下的虚拟机来说是个不错的选择.
ParNew收集器其实就是Serial的多线程版本, 除了使用多线程进行垃圾收集之外, 其余行为「控制参数、收集算法、回收策略等」和「Serial」收集器完全一样.
新生代采用复制算法,老年代采用标记-整理算法
PaNew收集器是许多运行在Server模式下的虚拟机的首先,除了Serial收集器之外,只有它能与**CMS(真正意义上的并发收集器)配合工作.**
Parallel Scavenge 收集器类似于ParNew 收集器。 那么它有什么特别之处呢?
Parallel Scavenge收集器关注是吞吐量(高效的复用cpu), CMS关注的点更多的是用户线程的停顿时间(提高用户体验)
所谓的吞吐量就是cpu中用于运行用户代码的时间与cpu总消耗的时间比值.
Parallel Scavenge收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量,如果对于垃圾回收器动作不太了解的话,手工优化内存的话可以选择把内存管理优化交给虚拟机去完成也是一个不错的选择.
-XX:+UseParallelGC // 使用Parallel收集器+ 老年代串行
-XX:+UseParallelOldGC // 使用Parallel收集器+ 老年代并行
Serial收集器的老年代版本.它同样是一个单线程收集器, 它主要用两大用途:
Parallel Scavenge收集器的老年代版本. 使用多线程与标记-整理算法, 在注重吞吐量及cpu资源的场合都可以优先考虑使用Parallel Scavenge收集器和Parallel Old收集器.
CMS「Concurrent Mark Sweep」收集器是一种以获取最短回收停顿时间为目标的收集器.它非常的适合在注重用户体验上的应用上使用.
CMS「Concurrent Mark Sweep」收集器是Hotspot虚拟机第一款真正意义上的并发收集器, 它第一次实现了 「让垃圾收集线程与用户线程(基本上)同时工作」
从名字中的Mark Sweep这两个词来看,CMS收集器是一种标记-清除算法实现的,它的运行过程相比于前面几种垃圾收集器更复杂一些.整个过程分为四个步骤:
初始标记
暂停所有的其它线程,并记录下直接与root相连的对象,速度很快.
并发标记
同时开启GC和用户线程,用一个闭包结构去记录可达对象。
但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。
因为用户线程可能会不断的更新引用域,所以GC线程无法保证可达性分析的实时性。
所以这个算法里会跟踪记录这些发生引用更新的地方。
重新标记
重新标记阶段就是为了__修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录__
这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短
并发清除
并发收集
低卡顿
但是它有明显的三个缺点:
G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.
被视为JDK1.7中HotSpot虚拟机的一个重要进化特征。它具备一下特点:
并行与并发
G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿时间.部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行.
分代收集
虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但是还是保留了分代的概念。
空间整合
与CMS的标记-清理算法不同,G1从整体来看是基于标记-整理算法实现的收集器;从局部上来看是基于复制算法实现的.
可预测的停顿
这是G1相对于CMS的另一个大优势,降低停顿时间是G1 和 CMS 共同的关注点,但G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内。