zl程序教程

您现在的位置是:首页 >  其他

当前栏目

垃圾收集器总结

2023-04-18 14:13:03 时间

垃圾收集器总结

常用垃圾收集器对比

垃圾收集器

串行/并行/并发

新生代/老年代

算法

目标

适用场景

Serial

串行

新生代

复制

低延迟优先

单 CPU 环境下的 Client 模式

Serial Old

串行

老年代

标记-整理

低延迟优先

单 CPU 环境下的 Client 模式、CMS 的后备预案

Parllel Scavenge

并行

新生代

复制

吞吐量优先

在后台运算而不需要太多交互的业务

Parallel Old

并行

老年代

标记-整理

吞吐量优先

在后台运算而不需要太多交互的业务

ParNew

并行

新生代

复制

低延迟优先

多 CPU 环境下,在 Server 模式与 CMS 配合使用

CMS

并发

老年代

标记-清除

低延迟优先

内存不大的 Java 应用

G1

并发

both

标记-整理+复制

低延迟优先

大内存的 Java 应用

常用垃圾收集器组合

  1. Serial + Serial Old:实现单线程的低延迟垃圾回收机制
  2. Parallel Scavenge + Parallel Old:实现多线程的高吞吐垃圾回收机制
  3. ParNew + CMS:实现多线程的低延迟垃圾回收机制
  4. G1:实现大内存 Java 应用的低延迟垃圾回收机制

如何选择垃圾收集器

  1. 吞吐量优先 or 低延迟优先
    1. 吞吐量优先 目标是充分利用多核 CPU 资源,让 CPU 尽可能多地处理业务,可以选择 Parallel GC,Parallel Scavenge + Parallel Old 的方案。
    2. 低延迟优先 目标是每次 GC 停顿时间尽量短,可以选择 CMS + ParNew 或直接使用 G1。
  2. 内存维度的考量
    1. 如果系统内存堆较大(超过 8G),同时希望整体来看平均 GC 时间可控,优先选择 G1。
    2. 如果内存很小,几百 MB,那使用什么 GC 其实影响都不大。
  3. 业务维度的考量
    1. 目前大部分 Java 应用系统,堆内存并不大(2G~4G),而且对 10ms 这种低延迟的 GC 暂停不敏感,也就是说处理一个业务流程,大概几百毫秒都是可以接受的, GC 暂停 50ms 还是 10ms 没多大区别。另一方面,系统的吞吐量反而往往是我们追求的重点,这时候就需要考虑采用并行 GC。
    2. 如果堆内存再大一些(比如超过 8G),则优先使用 G1。不然大内存下,一次 Full GC 的时间可能达到秒级别,业务上无法忍受。

垃圾收集技术发展脉络

  1. 串行 -> 并行 充分利用多核 CPU 的优势,大幅降低 GC 停顿时间,提升吞吐量。
  2. 并行 -> 并发 不只开多个 GC 线程并行回收,还将 GC 操作拆分为多个步骤,让很多繁重的任务和应用线程一起并发执行,减少了单次 GC 暂停持续的时间,这能有效降低业务系统的延迟。
  3. CMS -> G1 G1 可以说是在 CMS 基础上进行迭代和优化开发出来的,将整个堆划分为多个小 Region 进行增量回收,这样就更进一步地降低了单次 GC 暂停的时间。
  4. G1 -> ZGC ZGC 号称无停顿垃圾收集器,这又是一次极大的改进。 ZGC 和 G1 有一些相似的地方,但是底层的算法和思想又有了全新的突破。