1 GC的分类
前面文章主要是以串行GC收集器的内存模型展开论述,本章节主要是列举以及简述JVM提供的其他类型的GC收集器,每种类型都具有不同的性能特征,后续章节将展开详细的论述。
1.1 串行收集器(Serial Collector)
顾名思义,串行收集器是单线程模式,只使用一个线程去处理所有的GC收集工作,因为没有多线程之间的资源竞争,所以相对而言,效率较高。非常适合于单核处理器系统的使用场景,虽然不能充分利用多核处理器的优势,但也可以在多核处理器的运行环境中运行小应用(数据集通常只有约100M)。所以,JVM通过启发式的分析方法确定是否启动串行收集器的默认设置,或者用户可以显式地通过命令行参数(-XX:+UseSerialGC)设置。
1.2 并行收集器(Parallel Collector)
随着现代化计算机系统的迅速发展以及信息化时代的普及,单核处理器系统已经不能满足现实中的业务需求,所以JVM提供了并行收集器以满足多核处理器的系统的应用需求。
并行收集器也叫吞吐率收集器,其实现原理类似于串行收集器,都是基于分年龄代的实现原理,串行与并行的区别是,串行是单线程模式,而并行是多线程模式,也就是执行GC操作时候,并行收集器启动多个线程去并行化GC的收集操作,这可以提升GC的执行效率,以及缩短GC带来的暂停时间。
并行收集适合的使用场景包括中型数据集、大型数据集、多处理器以及多线程的运行环境,用户可以使用命令行参数-XX:+UseParallelGC显式地设置。
并行收集器另一个重要特性是并行压缩功能,并行压缩是在老年代堆区中并行化地执行major collection的操作,如果使用单线程执行major collection的操作,则会显著地限制了JVM的规模化的处理能力,也就是单线程操作会明显地降低JVM的性能、吞吐率等相关指标。如果显式地设置了命令行参数-XX:+UseParallelGC,则JVM默认启用了并行压缩功能,当然,也可以显式地设置命令行参数-XX:-UseParallelOldGC,则JVM默认关闭了并行压缩功能。
1.3 CMS收集器(Concurrent Mark Sweep Collector)
CMS收集器在JDK新版本中不再推荐使用,建议使用G1收集器代替。
CMS收集器的设计目标是为应用提供更短的GC暂停时间,也就是能以并发的方式分享系统的资源并能最大限度地不影响应用的正常运行。一般情况下,适用的场景是应用需要保存大量的长时间存在的存活对象,也就是老年代需要大堆区保存这些存活对象。
使用命令行参数XX:+UseConcMarkSweepGC指定使用CMS收集器。
1.4 G1收集器(Garbage-First Collector)
G1收集器主要是并发收集器, 其实现原理主要是使用多线程并发的模式去运行GC中一些主要的重要的工作负载(消耗资源较多的操作),这些GC工作负载与应用并行运作而不影响应用的正常业务逻辑的执行,所以没有GC暂停时间(没有stop the world的资源消耗),当然有小部分的GC工作负载需要付出GC暂停时间。G1收集器可以满足现代化应用系统的大规模扩展的应用需求,适用于拥有大容量内存的多处理器系统,G1收集器的设计目标是实现更短的GC暂停时间目标以及更高的吞吐量目标。
G1收集器是大部分应用系统中JVM的默认选择设定的GC收集器,当然也可以使用命令行参数-XX:+UseG1GC显式地设定。
1.5 ZGC收集器(Zero Garbage Collector)
ZGC收集器的设计目标是为大规模可扩展的、大内存容量、多核处理器的应用系统提供低延迟的特性,ZGC收集器是以并发模式并行地执行GC收集器全部重要的的工作负载(消耗资源较多的操作),这些操作不用付出GC暂停时间,不影响应用的正常运行。
ZGC能提供只有几毫秒的最大GC暂停时间,但需要付出一些吞吐率为代价,因为这两个指标是相互制约的。ZGC的暂停时间不依赖于正在使用的堆空间大小,其支持的内存空间大小从8MB到16TB的范围,用户可以使用命令行参数XX:+UseZGC开启此GC收集器。
1.6 如何选择收集器
理论上,JVM运用启发式的行为分析方法为应用系统提供默认的收集器的设定,除非有非常严格的暂停时间的需求,否则最好保持JVM的默认设置,但是具体问题具体分析,一个应用系统的所有配置必须以业务的实际需求为准。
如果操作系统的内存空间资源充足,最好的建议是给JVM分配尽可能多的堆空间,如果增加堆空间的方法还不能满足性能需求目标,则可以使用如下的建议选择一个合适的GC收集器并最优化地调整命令行参数:
- 对于小数据集(大小约100MB)的应用,建议使用串行收集器(Serial Collector),命令行参数是-XX:+UseSerialGC
- 对于单核处理器的应用系统或者没有GC暂停时间约束需求的应用系统,建议使用串行收集器(Serial Collector),命令行参数是-XX:+UseSerialGC
- 对于优先考虑性能的需求或者没有GC暂停时间约束的需求,可以接受大于1秒或者更长GC暂停时间的需求,建议保持系统的默认选择设置或者显式地使用命令行参数-XX:+UseParallelGC指定使用并行收集器
- 如果请求响应时间比总体吞吐率更重要,以及必须保持更短的GC暂停时间,建议显式地使用命令行参数-XX:+UseG1GC指定使用G1收集器
- 如果请求响应时间最重要(低延迟),建议显式地使用命令行参数-XX:UseZGC指定使用ZGC收集器
(未完待续)