JVM垃圾回收器深度底层原理分析与知识体系构建
一、垃圾回收的基本步骤
-
标记(Marking)
- 从GC Roots(如虚拟机栈、方法区静态变量、本地方法栈等)出发,遍历对象引用链,标记所有可达对象为存活对象,未被标记的则视为垃圾。
- 此阶段需暂停用户线程(Stop-The-World, STW),不同回收器优化策略不同,例如CMS和G1通过并发标记减少停顿。
-
清除(Sweeping)
- 根据标记结果清理垃圾对象,具体实现方式因算法而异:
- 标记-清除(Mark-Sweep) :直接回收未标记对象,但会产生内存碎片。
- 标记-整理(Mark-Compact) :移动存活对象以消除碎片,适合老年代。
- 复制(Copying) :将存活对象复制到另一块内存区域,适合新生代(如Survivor区)。
- 压缩(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,基于指针染色和读屏障实现并发。
- 适用于高吞吐量、低延迟的云原生应用。
四、选择与调优建议
-
版本差异
- JDK 8默认:Parallel Scavenge + Parallel Old。
- JDK 9+默认:G1。
- JDK 11+可选:ZGC(实验性功能)。
-
调优参数示例
- 启用G1:
-XX:+UseG1GC。 - 设置堆大小:
-Xms4g -Xmx4g(固定堆避免动态调整)。 - 日志分析:
-Xlog:gc*(JDK 9+)或-XX:+PrintGCDetails(JDK 8)。
- 启用G1:
-
场景推荐
- 高吞吐量:Parallel Scavenge/Old。
- 低延迟:G1或ZGC。
- 小内存:Serial。
五、垃圾回收的本质与哲学矛盾
垃圾回收的核心矛盾在于时空效率的平衡:时间维度上要减少STW(Stop-The-World)停顿时间,空间维度上要高效利用内存且避免碎片。这一矛盾驱动了GC算法的迭代。

底层逻辑框架:
- 对象存活判定:通过可达性分析构建对象图(Object Graph),以GC Roots为起点进行DFS/BFS遍历(三色标记法的数学抽象)
- 内存拓扑管理:分代假设(弱代假说)将内存划分为不同区域,通过空间换时间策略优化回收效率
- 并发控制:写屏障(Write Barrier)技术解决并发标记阶段的"对象消失"问题,具体实现有增量更新(CMS)和原始快照(G1)两种流派
一、算法演化与硬件协同
1. 分代算法的物理本质
- 新生代:采用复制算法(Copying)本质是顺序写+批量删除,利用空间局部性原理提升缓存命中率
- 老年代:标记-整理(Mark-Compact)通过内存重映射解决碎片,但需要处理指针更新问题(G1的Remembered Set)
2. 并发回收的硬件级优化
现代GC(如ZGC)利用地址视图转换实现并发压缩,关键技术包括:
- 指针染色(Colored Pointer):在64位指针中嵌入元数据
- 内存多重映射(mmap):同一物理内存映射到多个虚拟地址空间
四、主流回收器架构对比
| 回收器 | 内存模型 | 并发策略 | 碎片处理 | 适用场景 |
|---|---|---|---|---|
| CMS | 传统分代 | 并发标记+并行清除 | 不处理(标记清除) | 老年代低延迟 |
| G1 | Region分区 | 增量标记+并行复制 | 局部整理 | 大堆平衡型 |
| ZGC | 无分代 | 全并发染色指针 | 无碎片 | 超大堆(TB级)低延迟 |
| Shenandoah | Region分区 | 并发复制+读屏障 | 无碎片 | 中等堆高吞吐量 |
设计哲学差异:
- 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版本)选择合适的回收器,并通过参数调优实现最佳性能。
相关文章:
JVM垃圾回收器深度底层原理分析与知识体系构建
一、垃圾回收的基本步骤 标记(Marking) 从GC Roots(如虚拟机栈、方法区静态变量、本地方法栈等)出发,遍历对象引用链,标记所有可达对象为存活对象,未被标记的则视为垃圾。此阶段需暂停用户线程&…...
30.[前端开发-JavaScript基础]Day07-数组Array-高阶函数-日期Date-DOM
JavaScript的DOM操作 (一) 1 什么是DOM? 认识DOM和BOM 深入理解DOM 2 认识DOM Tree DOM Tree的理解 3 DOM的整体结构 DOM的学习顺序 DOM的继承关系图 document对象 4 节点、元素导航 节点(Node)之间的导航&…...
IP、网关、子网掩码、DNS 之间的关系详解
IP、网关、子网掩码、DNS 之间的关系详解 在计算机网络中,IP、网关、子网掩码和 DNS 是几个关键概念,它们协同工作,共同保障网络通信的顺畅。本文将详细探讨它们之间的关系。 一、IP 地址 IP 地址是网络中设备的唯一标识,如同现…...
【Day50 LeetCode】图论问题 Ⅷ
一、图论问题 Ⅷ 1、dijkstra算法 堆优化 采用堆来优化,适合节点多的稀疏图。代码如下: # include<iostream> # include<vector> # include<list> # include<queue> # include<climits>using namespace std;class myco…...
结构体介绍及内存大小分配问题
结构体 一.结构体的介绍1.1结构体的声明1.2匿名结构体1.3结构的自引用1.4使用 typedef 简化结构体类型名 二.结构体内存对齐2.1内存对齐规则2.2结构体内存对齐原因2.3修改默认对齐数 在 C 语言中,结构体(struct)是一种用户自定义的数据类型&a…...
halcon 条形码、二维码识别、opencv识别
一、条形码 函数介绍 create_bar_code_model * 1.创建条码读取器的模板 * 参数一:通用参数的名称,针对条形码模型进行调整。默认值为空 * 参数二:针对条形码模型进行调整 * 参数三:条形码模型的句柄。 create_bar_code_model (…...
Vue框架的使用 搭建打包 Vue的安全问题(Xss,源码泄露)
前言 什么是Vue? Vue是轻量级的js框架 可以帮助我们一键构造网站,打包app程序等 Vue的基本使用 1、构造框架并启用 新建一个 目录 使用终端切换到当前的目录 创建vue项目 第一个弹出使用语法我们选择是 剩下的全选择否 发现创建好了 接着进行…...
Java+SpringBoot+Vue+数据可视化的音乐推荐与可视化平台(程序+论文+讲解+安装+调试+售后)
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统介绍 在互联网技术以日新月异之势迅猛发展的浪潮下,5G 通信技术的普及、云计算能力…...
day2 - SpringBoot框架开发技术
主要内容 1. SpringBoot简介 2. 构建springboot工程 3. springboot接口返回json 4. springboot热部署 5. springboot资源属性配置 6. springboot整合模板引擎 7. springboot异常处理 8. springboot整合MyBatis 9. springboot整合redis 10. springboot整合定时任务 11. springbo…...
Flash-03
1-问题:Flash软件画两个图形,若有部分重合则变为一个整体 解决方法1:两个图形分属于不同的图层 解决方法2:将每个图形都转化为【元件】 问题2:元件是什么? 在 Adobe Flash(现在称为 Adobe Anim…...
新建菜单项的创建之CmpGetValueListFromCache函数分析
第一部分: PCELL_DATA CmpGetValueListFromCache( IN PHHIVE Hive, IN PCACHED_CHILD_LIST ChildList, OUT BOOLEAN *IndexCached, OUT PHCELL_INDEX ValueListToRelease ) 0: kd> dv KeyControlBlock 0xe1…...
【Word2Vec】Skip-gram 的直观理解(深入浅出)
01 什么是skip-gram 一句话来说就是,给定中心词,然后预测其周围的词: 02 模型结构 对于skip-gram来说,输入是一个[1 x V]维的ont-hot向量,其中V为词表大小,值为1的那一项就表示我们的中心词。经过一个[V x…...
在MacOS上打造本地部署的大模型知识库(一)
一、在MacOS上安装Ollama docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main 最后停掉Docker的ollama,就能在webui中加载llama模…...
(21)从strerror到strtok:解码C语言字符函数的“生存指南2”
❤个人主页:折枝寄北的博客 ❤专栏位置:简单入手C语言专栏 目录 前言1. 错误信息报告1.1 strerror 2. 字符操作2.1 字符分类函数2.2 字符转换函数 3. 内存操作函数3.1 memcpy3.2 memmove3.2memset3.3 memcmp 感谢您的阅读 前言 当你写下strcpy(dest, s…...
DeepSeek推出DeepEP:首个开源EP通信库,让MoE模型训练与推理起飞!
今天,DeepSeek 在继 FlashMLA 之后,推出了第二个 OpenSourceWeek 开源项目——DeepEP。 作为首个专为MoE(Mixture-of-Experts)训练与推理设计的开源 EP 通信库,DeepEP 在EP(Expert Parallelism)…...
1.2 Kaggle大白话:Eedi竞赛Transformer框架解决方案02-GPT_4o生成训练集缺失数据
目录 0. 本栏目竞赛汇总表1. 本文主旨2. AI工程架构3. 数据预处理模块3.1 配置数据路径和处理参数3.2 配置API参数3.3 配置输出路径 4. AI并行处理模块4.1 定义LLM客户端类4.2 定义数据处理函数4.3 定义JSON保存函数4.4 定义数据分片函数4.5 定义分片处理函数4.5 定义文件名排序…...
数据结构-顺序表专题
大家好!这里是摆子,今天给大家带来的是C语言数据结构开端-顺序表专题,主要介绍了数据结构和动态顺序表的实现,快来看看吧!记得一键三连哦! 1.数据结构的概念 1.1什么是数据结构? 数据结构是计…...
docker和containerd从TLS harbor拉取镜像
私有镜像仓库配置了自签名证书,https访问,好处是不需要处理免费证书和付费证书带来的证书文件变更,证书文件变更后需要重启服务,自签名证书需要将一套客户端证书存放在/etc/docker/cert.d目录下,或者/etc/containerd/c…...
kafka-关于ISR-概述
一. 什么是ISR ? Kafka 中通常每个分区都有多个副本,其中一个副本被选举为 Leader,其他副本为 Follower。ISR 是指与 Leader 副本保持同步的 Follower 副本集合。ISR 机制的核心是确保数据在多个副本之间的一致性和可靠性,同时在 …...
el-input实现金额输入
需求:想要实现一个输入金额的el-input,限制只能输入数字和一个小数点。失焦数字转千分位,聚焦转为数字,超过最大值,红字提示 效果图 失焦 聚焦 报错效果 // 组件limitDialog <template><el-dialog:visible.s…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
