Serial收集器
特点:
- 每次进行垃圾收集时,暂停其他所有线程。
- 新生代采用复制算法,老生代采用标记-整理算法
- 适合桌面程序
开启方法:-XX:+UseSerialGC
ParNew收集器
特点:
- 新生代使用多个线程进行垃圾回收
- 老年代单线程,所以不建议单独使用该收集器,老年代配合其他收集器
- 新生代采用复制算法,老生代采用标记整理算法
- 服务器首选算法
开启参数:-XX:+UseParNewGC
Parallel Scavenge收集器——对计算友好
特点:
- 吞吐量可以控制
- 新生带收集器
- 可以控制垃圾回收时间
应用场合
控制参数-XX:MaxGCPauseMillis 最大垃圾回收停顿时间-XX:GCTimeRatio 吞吐量大小-XX:+UseAdaptiveSizePolicy 内存调优委托给虚拟机管理
Parallel Old收集器
特点:
- 该收集器是
Parallel Scavenge的老年代版本 - 可并行回收
- 使用标记整理算法
应用场景:桌面程序
开启参数:-XX:UseParallelOldGC
Concurrent Mark Sweep(GMS)收集器
开启代码:-XX:+UseConcMarkSweepGC
特点:
- 以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。
- 实现了让垃圾收集线程与用户线程(基本上)同时工作。
- 采用“标记-清除算法”
过程一共包括四个步骤:初始标记: 暂停所有的其他线程,并记录下直接与 root 相连的对象,速度很快 ;并发标记: 同时开启 GC 和用户线程,用一个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。因为用户线程可能会不断的更新引用域,所以 GC 线程无法保证可达性分析的实时性。所以这个算法里会跟踪记录这些发生引用更新的地方。重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短并发清除: 开启用户线程,同时 GC 线程开始对为标记的区域做清扫。
G1收集器
开启代码:-XX:+UseG1GC
特点:
-
G1的设计原则是"首先收集尽可能多的垃圾(Garbage
First)"。因此,G1并不会等内存耗尽(串行、并行)或者快耗尽(CMS)的时候开始垃圾收集,而是在内部采用了启发式算法,在老年代找出具有高收集收益的分区进行收集。同时G1可以根据用户设置的暂停时间目标自动调整年轻代和总堆大小,暂停目标越短年轻代空间越小、总空间就越大; -
G1采用内存分区(Region)的思路,将内存划分为一个个相等大小的内存分区,回收时则以分区为单位进行回收,存活的对象复制到另一个空闲分区中。由于都是以相等大小的分区为单位进行操作,因此G1天然就是一种压缩方案(局部压缩);
-
G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独立的survivor(to space)堆做复制准备。G1只有逻辑上的分代概念,或者说每个分区都可能随G1的运行在不同代之间前后切换;
-
G1的收集都是STW的,但年轻代和老年代的收集界限比较模糊,采用了混合(mixed)收集的方式。即每次收集既可能只收集年轻代分区(年轻代收集),也可能在收集年轻代的同时,包含部分老年代分区(混合收集),这样即使堆内存很大时,也可以限制收集范围,从而降低停顿。