JVM垃圾回收器深度底层原理分析与知识体系构建

news/2025/2/27 8:12:23

一、垃圾回收的基本步骤

  1. 标记(Marking)

    • 从GC Roots(如虚拟机栈、方法区静态变量、本地方法栈等)出发,遍历对象引用链,标记所有可达对象为存活对象,未被标记的则视为垃圾。
    • 此阶段需暂停用户线程(Stop-The-World, STW),不同回收器优化策略不同,例如CMS和G1通过并发标记减少停顿。
  2. 清除(Sweeping)

    • 根据标记结果清理垃圾对象,具体实现方式因算法而异:
  • 标记-清除(Mark-Sweep) :直接回收未标记对象,但会产生内存碎片。
  • 标记-整理(Mark-Compact) :移动存活对象以消除碎片,适合老年代。
  • 复制(Copying) :将存活对象复制到另一块内存区域,适合新生代(如Survivor区)。
  1. 压缩(Compacting,可选)
    • 部分回收器(如Serial Old)在清除后整理内存,提升连续空间利用率。

二、垃圾回收器的分类

根据工作模式、线程数、内存区间等维度,垃圾回收器可分为以下类型:

1. 按线程数划分
  • 串行回收器(Serial GC)

    • 特点:单线程执行垃圾回收,全程STW。
    • 适用场景:客户端程序或小内存应用(如嵌入式系统)。
    • 代表:Serial(新生代)、Serial Old(老年代)。
  • 并行回收器(Parallel GC)

    • 特点:多线程并行回收,提高吞吐量,但STW时间仍较长。
    • 适用场景:注重吞吐量、多核CPU的服务器应用。
    • 代表:ParNew(新生代)、Parallel Scavenge(新生代)、Parallel Old(老年代)。
  • 并发回收器(Concurrent GC)

    • 特点:用户线程与GC线程交替工作,减少STW时间。
    • 适用场景:低延迟要求的应用(如实时系统)。
    • 代表:CMS(Concurrent Mark Sweep)、G1(Garbage-First)、ZGC。
2. 按分代划分
  • 新生代回收器

    • 使用复制算法,如Serial、ParNew、Parallel Scavenge。
    • 新生代分为Eden、Survivor区,对象存活时间短,回收频率高。
  • 老年代回收器

    • 使用标记-整理标记-清除算法,如CMS、Serial Old、Parallel Old。
    • 老年代对象存活时间长,回收频率低但耗时长。

三、主流垃圾回收器详解

1. Serial/Serial Old
  • 特点:单线程、STW、简单高效,适合小堆内存。
  • 缺点:暂停时间长,不适用于服务端。
2. ParNew
  • 特点:Serial的多线程版本,与CMS配合使用。
  • 缺点:在单核或低并发环境中可能不如Serial高效。
3. Parallel Scavenge/Parallel Old
  • 特点:以吞吐量为优先目标,适合后台计算型应用。
  • 参数:可通过-XX:MaxGCPauseMillis-XX:GCTimeRatio调整停顿时间和吞吐量。
4. CMS(Concurrent Mark Sweep)
  • 特点:并发标记、低延迟,但会产生内存碎片。
  • 阶段:初始标记(STW)→ 并发标记 → 重新标记(STW)→ 并发清除。
  • 问题:JDK 14后已废弃,因碎片化和无法处理大堆。
5. G1(Garbage-First)
  • 特点
    • 将堆划分为多个Region,优先回收垃圾最多的区域。
    • 支持并发标记、混合回收(同时处理新生代和老年代),且通过压缩减少碎片。
  • 适用场景:大堆内存(如几十GB)和低延迟要求(默认从JDK 9开始)。
6. ZGC
  • 特点
    • 支持TB级堆内存,STW时间不超过10ms,基于指针染色和读屏障实现并发。
    • 适用于高吞吐量、低延迟的云原生应用。

四、选择与调优建议

  1. 版本差异

    • JDK 8默认:Parallel Scavenge + Parallel Old。
    • JDK 9+默认:G1。
    • JDK 11+可选:ZGC(实验性功能)。
  2. 调优参数示例

    • 启用G1:-XX:+UseG1GC
    • 设置堆大小:-Xms4g -Xmx4g(固定堆避免动态调整)。
    • 日志分析:-Xlog:gc*(JDK 9+)或-XX:+PrintGCDetails(JDK 8)。
  3. 场景推荐

    • 高吞吐量:Parallel Scavenge/Old。
    • 低延迟:G1或ZGC。
    • 小内存:Serial。

五、垃圾回收的本质与哲学矛盾

垃圾回收的核心矛盾在于时空效率的平衡:时间维度上要减少STW(Stop-The-World)停顿时间,空间维度上要高效利用内存且避免碎片。这一矛盾驱动了GC算法的迭代。

底层逻辑框架

  1. 对象存活判定:通过可达性分析构建对象图(Object Graph),以GC Roots为起点进行DFS/BFS遍历(三色标记法的数学抽象)
  2. 内存拓扑管理:分代假设(弱代假说)将内存划分为不同区域,通过空间换时间策略优化回收效率
  3. 并发控制:写屏障(Write Barrier)技术解决并发标记阶段的"对象消失"问题,具体实现有增量更新(CMS)和原始快照(G1)两种流派

一、算法演化与硬件协同

1. 分代算法的物理本质
  • 新生代:采用复制算法(Copying)本质是顺序写+批量删除,利用空间局部性原理提升缓存命中率
  • 老年代:标记-整理(Mark-Compact)通过内存重映射解决碎片,但需要处理指针更新问题(G1的Remembered Set)
2. 并发回收的硬件级优化

现代GC(如ZGC)利用地址视图转换实现并发压缩,关键技术包括:

  • 指针染色(Colored Pointer):在64位指针中嵌入元数据
  • 内存多重映射(mmap):同一物理内存映射到多个虚拟地址空间

四、主流回收器架构对比

回收器内存模型并发策略碎片处理适用场景
CMS传统分代并发标记+并行清除不处理(标记清除)老年代低延迟
G1Region分区增量标记+并行复制局部整理大堆平衡型
ZGC无分代全并发染色指针无碎片超大堆(TB级)低延迟
ShenandoahRegion分区并发复制+读屏障无碎片中等堆高吞吐量

设计哲学差异

  • CMS:时间优先,通过并发降低停顿,容忍内存碎片
  • G1:空间可预测,建立Region回收价值模型
  • ZGC:硬件驱动,利用64位地址空间特性突破传统限制

五、关键扩展

1. 三色标记的工程实现
  • 漏标问题的两种解决方案:
    • 增量更新(CMS) :记录新增引用(类似数据库redo log)
    • 原始快照(G1) :记录删除引用(类似MVCC快照)
// 写屏障伪代码示例(G1风格)
void oop_field_store(oop* field, oop new_value) {
    pre_write_barrier(field); // 记录旧值
    *field = new_value; 
    post_write_barbarrier(field, new_value); // 记录新值
}

2. 停顿时间控制机制
  • G1的预测模型:基于Markov链建立Region回收价值预测
  • ZGC的Phase机制:将GC过程分解为10+个可中断的phase
3. 内存分配与GC联动
  • TLAB(Thread Local Allocation Buffer) :每个线程独享的分配缓冲区,避免全局锁竞争
  • Humongous Object:G1对超大对象的特殊处理(直接放入老年代Region)

五、总结

JVM垃圾回收器的演进体现了对性能、延迟和内存管理的持续优化。从早期的单线程Serial到并发的G1、ZGC,开发者需根据应用场景(如堆大小、延迟要求、JDK版本)选择合适的回收器,并通过参数调优实现最佳性能。


http://www.niftyadmin.cn/n/5869783.html

相关文章

224Gb/s信号完整性测试治具设计(二)

第一篇看这里: 224Gb/s信号完整性测试治具设计(一)-CSDN博客 聚焦解决方案空间 始终满足 1.6T 测试夹具的目标插入损耗要求 IEEE P802.3dj 中当前的插入损耗规范要求,在 53.125 GHz 频率下,主机合规板&#xff08…

无人机遥控器的亮度 和 两个工作频率

工作频率 2.4000-2.4835 GHz , 5.725-5.850 GHz 1.这是一个无人机的遥控器的两个工作频率,为什么会有两个工作频率? 无人机的遥控器采用双频段设计(2.4GHz 和 5.8GHz),主要是为了解决以下问题并优化性…

HTTP非流式请求 vs HTTP流式请求

文章目录 HTTP 非流式请求 vs 流式请求一、核心区别 服务端代码示例(Node.js/Express)非流式请求处理流式请求处理 客户端请求示例非流式请求(浏览器fetch)流式请求处理(浏览器fetch) Python客户端示例&…

react native中如何实现吸顶的效果

rn中实现吸顶效果用ScrollView、SectionList、FlatList都可以实现&#xff0c;因为SectionList、FlatList都是继承自ScrollView&#xff0c;都会有stickyHeaderIndices属性&#xff0c;这个属性是一个数组&#xff0c;可以决定下标为几的组件有吸顶的效果。 <FlatListdata{…

【EB-06】SystemCreator dbc转arxml

SystemCreator dbc转arxml 1. SystemCreator 意义2. SystemCreator使用方法2.1 实现步骤2.2 参考官方文档方法1. SystemCreator 意义 EB Tresos 对dbc直接导入的支持不是很完善,dbc也不是AUTOSAR标准的数据库文件,EB建议所有通信矩阵通过ARXML交互比较合理(AUTOSAR定义的)…

idea中或pycharm中编写Markdown文件

参考 ltjt_aiseek: seek_backend_py 项目 数智科技ai探索API接口开发 1. 安装 Django 框架 在开始创建 Django 项目之前&#xff0c;需要先安装 Django 框架。可以通过 PyCharm 的终端或者系统的命令行工具来完成安装。 使用 PyCharm 终端安装 打开 PyCharm&#xff0c;如果…

J-LangChain - RAG - PDF问答

系列文章索引 J-LangChain 入门 在现代自然语言处理&#xff08;NLP&#xff09;中&#xff0c;基于文档内容的问答系统变得愈发重要&#xff0c;尤其是当我们需要从大量文档中提取信息时。通过结合文档检索和生成模型&#xff08;如RAG&#xff0c;Retrieval-Augmented Gener…

excel单、双字节字符转换函数(中英文输入法符号转换)

在Excel中通常使用函数WIDECHAR和ASC来实现单、双字节字符之间的转换。其中 WIDECHAR函数将所有的字符转换为双字节&#xff0c;ASC函数将所有的字符转换为单字节 首先来解释一下单双字节的含义。单字节一般对应英文输入法的输入&#xff0c;如英文字母&#xff0c;英文输入法…