✅有一个银行系统,对实时性要求比较高,你会怎么选择垃圾回收器?

✅有一个银行系统,对实时性要求比较高,你会怎么选择垃圾回收器?

典型回答

这个题目中比价关键的一个词是“实时性要求比较高”,**实时性意味着延迟低,延迟低意味着停顿时间短。意味着STW的时间短。**那么就需要选择STW耗时短的垃圾回收器。

✅什么是STW?有什么影响?

但是,这个问题很难回答,因为最主要的就是根据不同的JDK版本,可能选择的结果是不一样的。


我们从高往低了开始说。

JDK版本 垃圾收集器选择
>= JDK 12 Shenandoah GC 或者 ZGC
>= JDK 11 & < JDK 12 ZGC
>=JDK 7 G1
< JDK 7 Parallel Scavenge + CMS

垃圾收集器有几种,首先我们肯定要排除Serial GC和Serial Old这两个串行的垃圾回收器了。然后就在区分为并发垃圾回收器和并行垃圾回收器。

✅说一说JVM的并发回收和并行回收

并行回收其实就是Parallel Scavenge,Parallel Old,ParNew等收集器。这种垃圾回收器更加关注的是吞吐量(吞吐量=代码运行时间/(代码运行时间+垃圾收集时间),在这个公式里,垃圾收集时间是分母的一部分,但是他并不是全部,他只能一定程度上影响吞吐量,但是这几种垃圾回收器,会综合看吞吐量的指标,并不会极端的优化垃圾收集时间。

而我们说的并发回收比较典型的就是 **CMS、G1等,他们更加关注的垃圾回收的停顿时间。其实主要就是引入了三色标记法。**引入三色标记法之后,就是把STW的时间缩短了,具体原因参考:


✅介绍下CMS的垃圾回收过程

所以,如果能选择CMS和G1肯定要比Parallel Scavenge,Parallel Old,ParNew这几个更适合我们的这个场景。而且G1是整堆回收器,而CMS是老年代回收器,所以如果用G1的话,一个就够了,如果用CMS的话,还需要搭配一个年轻代的回收器,比如Parallel Scavenge。

所以,如果是JDK 1.7之后的版本的话(小于JDK 11),建议直接上G1了,当然,G1堆内存大小有一定要求,一般要求4G起步,8G以上最好。G1可以把STW时长控制在10ms-100ms左右。

如果是JDK版本更新的话,比如JDK 11以后,就可以考虑Shenandoah GC 和 ZGC这两个超低延迟垃圾收集器了,他们适用于超大堆内存。暂停时间通常在10ms以下,适合对响应时间有极高要求的应用。