Java HotSpot虚拟机包含了三类垃圾收集器,每一类都有不同的性能特征。
串行(Serial)收集器
串行收集器在单线程中进行垃圾回收,由于没有线程之间的切换,因此垃圾回收工作相对较高效。
对单核处理器的硬件来说,串行收集器是最佳选择。因为它无法发回多核设备的优势。只适合小型应用程序。
Serial收集器在某些设备和操作系统上是默认配置,当然你也可以可以使用
-XX:+UseSerialGC
参数手动指定HotSpot虚拟机使用串行收集器。
并行(Parallel)收集器
parallel收集器也被称为 throughput collector(吞吐量优先)收集器,它与Serial收集器的主要区别在于,垃圾回收过程在多线程中进行,加速了垃圾回收过程。parallel收集器一般用于运行在多核、多线程设备上的中大型应用程序。
可以通过
-XX:+UseParallelGC
启用parallel收集器。
并行压缩功能是允许并行收集器并行的处理老年代的回收工作。不启用并行压缩的情况下,老年代收集采用单线程。
默认情况下, 并行压缩是随着-XX:+UseParallelGC默认开启的。也可以通过-XX:-UseParallelOldGC关闭并行压缩。
并发(Concurrent)收集器
CMS(Concurrent Mark Sweep,并发标记清除)收集器和G1(Garbage First)收集器是最主要的两个并发垃圾收集器。并发收集器处理与应用程序同时工作。
G1收集器:
具有超大内存、多处理器的设备上采用。它可以满足停顿时间的目标,同时达到高吞吐量。
在某些硬件和操作系统上,G1是默认开启的。你也可以通过-XX:+UseG1GC
参数手动开启。
CMS收集器:
此垃圾收集器用于那些期望缩短垃圾回收造成的停顿,并且可以接受跟垃圾收集共享资源的应用程序。
通过-XX:+UseConcMarkSweepGC参数启用CMS收集器。
CMS收集器在JDK9中废弃了。
选择垃圾收集器
除非你的应用程序对停顿时间有折着苛刻的要求,否则请首先运行应用程序,让虚拟机做出选择。
如果需要,通过尝试调整堆大小来改善性能。如果性能依然无法达到预期,就按以下方针选择垃圾收集器:
- 如果100MB左右的小型应用,使用串行收集器。-XX:+UseSerialGC
- 如果应用程序运行在单处理器设备上,且对停顿时间没有要求,则使用串行收集器。-XX:+UseSerialGC
- 如果应用程序对性能有较高的要求、对停顿时间没有特别要求或者1秒甚至更长的停顿也能接受的话。则可让虚拟机选择垃圾收集器或者通过–XX:+UseParallelGC指定并行收集器
- 如果响应时间的重要性大于吞吐量,同时要求停顿时间小于1秒,则选择并发收集器。G1或并发CMS收集器(通过XX:+UseG1GC,-XX:+UseConcMarkSweepGC开启)
这些guideline只是选择垃圾收集器的开始,因为影响性能因素有很多:堆大小、应用持有的实时数据量、处理器的速度和数量等。pause-time对这些因素很敏感,因此前面提到的1秒阈值只是个近似值。在许多堆大小和硬件的组合下,并行收集器的停顿时间可能超过一秒。同理,并发收集器并不能保证停顿时间就能少于1秒。
如果建议的收集器无法达到性能预期。首先尝试调整堆大小和分代大小来达到预期,如果还是不行,则尝试更换垃圾收集器。
使用并发收集器减少停顿,使用并行收集器增加在多处理器设备上的吞吐量。