你们线上用的什么垃圾收集器?为什么要用它?
常见的垃圾回收器:
新生代收集器(高吞吐量): Serial、ParNew、Parallel Scavenge
老年代收集器(SWT停顿时间): Serial Old、CMS、Parallel Old
新生代和老年代收集器: G1、ZGC、Shenandoah
每种垃圾回收器之间不是独立操作的,下图表示垃圾回收器之间有连线表示,可以协作使用:
一般的垃圾回收器搭配为:
JDK8 :
- ParNew(复制算法。并行。 单核情况下不如Serial) + CMS(标记清除。并发)
-
- 适合类型:适用于需要低停顿时间的应用,如 Web 服务器、应用服务器。
- 示例应用:电商网站、在线游戏、高并发服务器。
- 4-8G可以用ParNew+CMS
- Parallel Scavenge(复制算法。并行,吞吐量优先收集器) + Parallel Old(标记整理。并行)
-
- 适合类型:适用于多核处理器的高吞吐量应用。
- 示例应用:科学计算、数据分析、大规模数据处理。
- 4G以下可以用parallel
- G1 (年轻代:复制 老年代:标记-整理)JDK 9 默认的收集器 要求尽可能可控 GC 停顿时间;内存占用较大的应用。
-
- 适合类型:适用于需要可预测停顿时间的应用,尤其是大堆内存的应用。
- 示例应用:企业级应用、中大规模 Web 服务、应用响应时间要求高的系统。
- 8G以上可以用G1
zgc:适用于需要极低停顿时间(毫秒级别)的大内存应用
-
- 适合类型:适用于需要极低停顿时间(毫秒级别)的大内存应用。
- 示例应用:内存密集型数据库、金融交易系统、云服务。
- 几百G以上用ZGC
怎么查默认用的GC是什么呢?
可以使用命令:
java -XX:+PrintCommandLineFlags -version
可以看到有这么一行:
-XX:+UseParallelGC
UseParallelGC = Parallel Scavenge + Parallel Old,表示的是新生代用的Parallel Scavenge收集器,老年代用的是Parallel Old 收集器。
那为什么要用这个呢?默认的呗。
当然面试肯定不能这么答。
Parallel Scavenge的特点是什么?
高吞吐,我们可以回答:因为我们系统是业务相对复杂,但并发并不是非常高,所以希望尽可能的利用处理器资源,出于提高吞吐量的考虑采用Parallel Scavenge + Parallel Old的组合。
当然,这个默认虽然也有说法,但不太讨喜。
还可以说:
采用Parallel New+CMS的组合,我们比较关注服务的响应速度,所以采用了CMS来降低停顿时间。
或者一步到位:
我们线上采用了设计比较优秀的G1垃圾收集器,因为它不仅满足我们低停顿的要求,而且解决了CMS的浮动垃圾问题、内存碎片问题。