当前位置: 首页 > news >正文

深入理解JVM垃圾收集器:垃圾收集器

目录

前言

1. 如何判断对象"已死"?

1.1 引用计数算法(Java未采用)

1.2 可达性分析算法(Java采用)

1.3 Java中的四种引用类型

2. 垃圾收集算法

2.1 标记-清除算法(Mark-Sweep)

2.2 标记-复制算法(Copying)

2.3 标记-整理算法(Mark-Compact)

2.4 分代收集算法(Generational Collection)

3. 经典垃圾收集器

3.1 Serial收集器

3.2 ParNew收集器

3.3 Parallel Scavenge收集器

3.4 Serial Old收集器

3.5 Parallel Old收集器

3.6 CMS收集器(Concurrent Mark Sweep)

3.7 G1收集器(Garbage-First)

4. 新一代垃圾收集器

4.1 ZGC(Z Garbage Collector)

4.2 Shenandoah

5. 如何选择垃圾收集器?

6. 实战调优建议

6.1 通用参数配置

6.2 G1调优示例


前言

作为Java开发者,我们几乎每天都在与JVM打交道,但你是否真正了解JVM是如何自动管理内存、回收垃圾对象的?本文将带你深入探讨JVM垃圾收集器的核心知识,帮助你编写出更高效、更稳定的Java应用。

1. 如何判断对象"已死"?

在了解垃圾收集器之前,我们首先要明白JVM如何判断哪些对象可以被回收。

1.1 引用计数算法(Java未采用)

早期的一种简单策略:每个对象有一个引用计数器,被引用时+1,引用失效时-1。虽然简单高效,但无法解决循环引用问题,因此Java并未采用。

1.2 可达性分析算法(Java采用)

这是JVM使用的算法:通过一系列称为"GC Roots"的对象作为起点,向下搜索,搜索走过的路径称为"引用链"。当一个对象到GC Roots没有任何引用链相连时,则证明此对象不可用。

GC Roots包括:

  1. 虚拟机栈中引用的对象
  2. 方法区中类静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中JNI引用的对象

1.3 Java中的四种引用类型

Java根据引用强度不同,提供了灵活的引用方式:

引用类型

回收时机

使用场景

强引用

永不回收(除非显式置null)

普通对象创建

软引用

内存不足时回收

实现内存敏感缓存

弱引用

下次GC时回收

避免内存泄漏(如WeakHashMap)

虚引用

无法通过get()获取对象,仅用于跟踪对象回收

管理堆外内存

2. 垃圾收集算法

垃圾收集器是基于特定算法实现的,主要有以下三种基础算法:

2.1 标记-清除算法(Mark-Sweep)

最基础的算法,分为"标记"和"清除"两个阶段:

  1. 优点:实现简单
  2. 缺点:产生内存碎片,效率不高

2.2 标记-复制算法(Copying)

将内存分为两块,每次只使用一块:

  1. 优点:没有碎片,高效
  2. 缺点:内存利用率仅50%
  3. 应用:主要用于新生代(HotSpot采用8:1:1的比例优化)

2.3 标记-整理算法(Mark-Compact)

标记过程与"标记-清除"一样,但后续步骤不是直接清理,而是让所有存活对象向一端移动:

  1. 优点:没有碎片,内存利用率高
  2. 缺点:移动对象成本高
  3. 应用:主要用于老年代

2.4 分代收集算法(Generational Collection)

现代商用虚拟机大都采用此算法,根据对象存活周期不同将内存划分为几块:

  1. 新生代:对象朝生夕死,采用复制算法
  2. 老年代:对象存活率高,采用标记-清除或标记-整理算法

3. 经典垃圾收集器

JVM提供了多种垃圾收集器,适用于不同场景:

3.1 Serial收集器

特点:单线程,Stop-The-World(STW)
适用场景:客户端模式,小内存应用
配置参数-XX:+UseSerialGC

3.2 ParNew收集器

特点:Serial的多线程版本
适用场景:与CMS配合使用
配置参数-XX:+UseParNewGC

3.3 Parallel Scavenge收集器

特点:吞吐量优先,多线程
适用场景:后台运算,不需要太多交互
配置参数-XX:+UseParallelGC

3.4 Serial Old收集器

特点:Serial的老年代版本,单线程,标记-整理算法
配置参数-XX:+UseSerialGC

3.5 Parallel Old收集器

特点:Parallel Scavenge的老年代版本,多线程,标记-整理算法
配置参数-XX:+UseParallelOldGC

3.6 CMS收集器(Concurrent Mark Sweep)

特点:以获取最短回收停顿时间为目标,并发收集
工作流程

  1. 初始标记(STW)
  2. 并发标记
  3. 重新标记(STW)
  4. 并发清除

优点:低停顿
缺点:对CPU资源敏感,无法处理浮动垃圾,产生碎片
配置参数-XX:+UseConcMarkSweepGC

3.7 G1收集器(Garbage-First)

特点:面向服务端应用,兼顾吞吐量和停顿时间
创新点:将堆划分为多个Region,优先回收价值最大的Region
工作流程

  1. 初始标记(STW)
  2. 并发标记
  3. 最终标记(STW)
  4. 筛选回收(STW)

配置参数-XX:+UseG1GC

4. 新一代垃圾收集器

4.1 ZGC(Z Garbage Collector)

特点:低延迟,支持TB级堆内存,停顿时间不超过10ms
适用场景:超大堆内存应用
配置参数-XX:+UseZGC(JDK15+)

5. 如何选择垃圾收集器?

选择收集器需要考虑应用特点:

场景

推荐收集器

参数配置

单核CPU或小内存客户端

Serial

-XX:+UseSerialGC

多核CPU追求高吞吐

Parallel Scavenge/Old

-XX:+UseParallelGC -XX:+UseParallelOldGC

多核CPU追求低延迟(JDK8)

CMS

-XX:+UseConcMarkSweepGC

大堆内存,平衡吞吐和延迟

G1

-XX:+UseG1GC

超大堆内存,极致低延迟

ZGC

-XX:+UseZGC

6. 实战调优建议

6.1 通用参数配置

# 设置堆大小
-Xms4g -Xmx4g# 设置年轻代大小
-Xmn2g# 设置线程栈大小
-Xss256k# 开启GC日志
-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

6.2 G1调优示例

java -Xms4g -Xmx4g -XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \      # 目标最大停顿时间
-XX:InitiatingHeapOccupancyPercent=45 \  # 触发并发标记的堆使用率
-XX:ConcGCThreads=4 \           # 并发GC线程数
-XX:G1ReservePercent=10 \       # 保留内存比例
-jar your-application.jar

http://www.dtcms.com/a/349840.html

相关文章:

  • Vue3 + Golang Gin 实现客服实时聊天系统(WebSocket + Socket.IO 详解)
  • Maven、Spring Boot、Spring Cloud以及它们的相互关系
  • iptables 防火墙技术详解
  • 如何通过虚函数实现多态?
  • 文入门Ubuntu:从零到精通的Linux之旅
  • 数学建模-整数规划(IP)
  • FunASR语音识别框架流式识别模型切换
  • SpringBoot的条件装配原理
  • SpringBoot3集成Oauth2.1——10重启程序Token失效(RSA持久化)
  • Java项目-苍穹外卖_Day1
  • Visual Studio 2022调试Eigen库查看矩阵与向量的值
  • 大模型知识点之矩阵乘以向量
  • springboot:前后端调用(axios发送异步请求)
  • 那我现在有3个输入 9层神经元 每层神经元数为 3 9 3 5 6 2 3 9 8 请给出我所有的权重矩阵
  • 图论水题5
  • ansible的搭建与安装
  • BIO、NIO 和 AIO
  • 智慧城市SaaS平台/交通设施运行监测系统之桥梁运行监测、城市道路塌陷风险运行监测系统架构内容
  • v-slot 与 slot-scope区别
  • 开源零信任本地化部署实战指南:Keycloak + OpenZiti 完整方案
  • [element-plus] el-table在行单击时获取行的index
  • JAVA高级工程师--云服务模式多租户SAAS项目商业模式架构全景
  • 【数据可视化-98】2025年上半年地方财政收入Top 20城市可视化分析:Python + Pyecharts打造炫酷暗黑主题大屏
  • 【Java基础】快速掌握Java泛型机制:基本概念与具体应用
  • 工具系列:JsonViewKit
  • Frida 加密解密算法实现与应用指南
  • kafka 原理详解
  • 代码随想录算法训练营30天 | ​​01背包理论基础、416. 分割等和子集
  • Radxa Rock 5B vs Rock 5B+ 、香橙派、鲁班猫、正点原子及RK3588 的AI/音视频任务的选择
  • springboot项目每次启动关闭端口仍被占用