JVM 垃圾收集器相关知识总结

一、基本概念

垃圾收集(Garbage Collection,GC)是Java等编程语言中用于自动管理内存的一种机制。它通过回收不再使用的对象所占用的内存,以避免内存泄漏和确保程序的稳定运行。

二、收集方式分类

按工作模式不同:指的是GC线程和工作线程是否一起运行

  • 独占垃圾回收器:只要GC在工作,STW 一直进行到回收完毕,工作线程才能继续执行;

  • 并发垃圾回收器:让GC线程垃圾回收的某些阶段 可以和 工作线程一起进行。

按回收线程数:指的是GC线程是否串行或并行执行

  • 串行垃圾回收器:一个GC线程完成内存资源的回收工作;

  • 并行垃圾回收器:多个GC线程同时一起完成内存资源的回收工作,充分利用CPU的多核并发执行的计算资源。

三、常见垃圾回收器方案

  • 新生代可以适用的垃圾回收器:Serial(串行收集器)、ParNew(并行年轻代收集器)、Parallel Scavenge(并行回收器)。

    Serial:单线程的年轻代垃圾回收器,适用于单核处理器或对暂停时间要求不高的场景。

    ParNew:Serial 的多线程版本,可利用多核处理器优势,在多处理器环境下能更快完成垃圾回收。

    Parallel Scavenge:关注吞吐量的年轻代垃圾回收器,适合在后台运行且不需要快速响应的任务,目标是在单位时间内完成更多工作。

  • 老年代可以适用的垃圾回收器:CMS(并发标记-清除收集器)、Serial Old(串行老年代收集器)、Parallel Old(并行老年代收集器)。

    CMS(Concurrent Mark Sweep):以获取最短回收停顿时间为目标的老年代垃圾回收器,在垃圾回收过程中能与应用程序线程并发执行,适合对响应时间敏感的应用。

    Serial Old:单线程的老年代垃圾回收器,通常作为 CMS 发生 Concurrent Mode Failure 时的后备方案。

    Parallel Old:Parallel Scavenge 对应的老年代版本,关注吞吐量,与 Parallel Scavenge 搭配使用,在多核处理器上能有效利用资源进行垃圾回收。

  • 新生代和老年代混合回收器:G1(Garbage First 收集器)和 ZGC(Z Garbage Collector)回收器。

    G1(Garbage - First):整体上采用标记 - 整理算法,局部采用复制算法,不再区分传统的年轻代和老年代,而是将堆划分为多个 Region。它能预测停顿时间,优先回收价值最大的 Region,适用于大内存且对停顿时间有严格要求的应用。

    ZGC(Z Garbage Collector):低延迟垃圾回收器,支持 TB 级别的堆内存,停顿时间可控制在 10ms 以内,通过着色指针和读屏障等技术实现并发回收。

四、串行收集器Serial

单线程、独占式串行,采用复制算法0,简单高效但会造成STW。这是最基础的单线程垃圾回收器,在进行垃圾回收时,整个应用程序会完全停顿,直到回收完成。

  • 新生代:采用复制算法(将存活对象复制到空闲区域,清理原区域);

  • 老年代:采用标记 - 整理算法(标记存活对象,将其紧凑排列以消除碎片)。

优缺点

  • 优点:实现简单,内存占用极低(无需多线程协调开销),单线程下效率高(无线程切换成本);

  • 缺点:STW 时间长(随堆大小增加而增长),无法利用多 CPU 资源,不适合高并发场景。

适用场景

  • 客户端应用(如桌面程序、工具类软件),堆内存较小(通常小于 1GB);

  • 单 CPU 环境或资源受限的嵌入式设备。

五、并行回收收集器Parallel

随着硬件资源的升级,包括内存空间的增大和 CPU 的多核化,传统的 Serial 垃圾收集器面临着性能瓶颈。由于它采用单线程执行垃圾回收操作,无法充分利用多核 CPU 的优势,导致在处理大内存空间时性能下降,垃圾回收时间变得更长。

为了充分发挥多核 CPU 的优势,JVM 推出了 Parallel 收集器系列。Parallel 收集器的设计思想是利用多线程并行执行垃圾回收操作,以提高整个垃圾收集过程的并行度和性能。

相比于传统的 Serial 收集器,Parallel 收集器能更好地适应现代应用的需求,特别是大型内存堆和高吞吐量的场景。

多线程并行、独占式,会产生STW,使用复制算法关注调整吞吐量。此收集器核心目标是提高吞吐量:吞吐量 = 运行用户代码时间/(运行用户代码时间+垃圾收集时间)

  • 新生代:多线程执行复制算法,并行收集;

  • 老年代:多线程执行标记 - 整理算法,并行收集;

注:仍会触发 STW,但因多线程并行,STW 时间比 Serial GC 短。

优缺点

  • 优点:吞吐量高(适合后台计算),多 CPU 下效率优于 Serial GC,可通过参数(如-XX:MaxGCPauseMillis)控制最大 STW 时间;

  • 缺点:STW 时间仍可能较长(尤其堆较大时),对响应时间敏感的应用不友好。

适用场景

  • 批处理任务(如数据分析、日志处理);

  • 适合在后台运算而不需要太多交互的任务,优先追求高吞吐量而非低延迟。

六、无代限制收集器G1

随着硬件资源的不断升级,可用的内存资源越来越多,这对于垃圾收集器的发展提出了新的挑战。

传统的垃圾收集器采用物理分区的方式将内存分为老年代、新生代、永久代或 MetaSpace,但随着可用内存的增加,某一分代区域的大小可能会达到几十上百 GB。在这种情况下,传统的物理分区收集方式会导致垃圾扫描和清理时间变得更长,性能下降。

G1 垃圾收集器摒弃了传统的物理分区方式,而是将整个内存分成若干个大小不同的 Region 区域。每个Region 在逻辑上组合成各个分代,这样做的好处是可以以 Region 为单位进行更细粒度的垃圾回收。G1 垃圾收集器在进行垃圾回收时,可以针对单个或多个 Region 进行回收,从而提高了收集效率和性能。

核心思想

"优先回收垃圾最多的 Region"(Garbage-First),通过混合收集(同时回收部分新生代和老年代 Region)平衡吞吐量和延迟。

优缺点

  • 优点:兼顾吞吐量和响应时间,STW 可控(适合对延迟有要求的场景),支持大堆且内存碎片少;

  • 缺点:内存占用和 CPU 消耗较高(需维护 Region 元数据),小堆下性能可能不如 Parallel GC。

适用场景

  • 大型企业级应用(如电商平台、支付系统);

  • 堆内存较大,需要平衡吞吐量和响应时间的服务。

七、如何根据应用类型选择垃圾收集器?

选择的核心依据是应用的核心需求(延迟 / 吞吐量)、资源限制(堆大小、CPU 核心数)等,一般情况下可使用以下原则:

  • 客户端或较小程序,内存使用量不大,单 CPU 或资源受限,可以使用串行回收Serial

  • 对于服务端大型计算,有限吞吐量,可以使用并行回收Parallel

  • 大型WEB应用,用户端不愿意等待,尽量少的STW,优先响应时间(低延迟),可以使用无代限制收集器G1

相关推荐
weixin_436525073 小时前
Windows - Maven 安装到 IDEA 配置全流程
java·maven·intellij-idea
启山智软3 小时前
APS系统适合哪些行业或企业规模
java·商城开发
在等晚安么3 小时前
记录自己写项目的第三天,springbot+redis+rabbitma高并发项目
java·spring boot·redis·1024程序员节
OkGogooXSailboat4 小时前
flume的log4j日志无输出排查
java·flume·1024程序员节
想睡好4 小时前
express中间件(java拦截器)
java·中间件·express
兢兢业业的小白鼠4 小时前
Java常用中间件整理讲解——Redis,RabbitMQ
java·中间件·java-rabbitmq·1024程序员节
鱼儿也有烦恼4 小时前
快速学完 LeetCode top 1~50 [特殊字符]
java·算法·leetcode·1024程序员节
独自破碎E4 小时前
LeetCode 380: O(1) 时间插入、删除和获取随机元素
java·算法·leetcode
信仰_2739932435 小时前
Mybatis一级缓存
java·缓存·mybatis