深入理解Java垃圾回收(GC)
1. 概述我自己对GC的理解为 : new 的新对象会先进入eden_space里面 然后eden_space满了以后会触发yongGC将eden_space里面的对象 S0(初次可能是空的) 的所有存活对象全部复制到S1,这个时候会有判断如果S1没有满,则会清空S0 和eden_space里面所有的对象,满了则会将存活时间长的优先晋升到老年代,如果还是满的则将剩下的存活时间一般或者小的也开始晋升到老年代如果还是不行就全部晋升到老年代,之后再去清空S0和eden_space的所有对象,下次如果在发生yongGC的时候S0和S1角色就会发生互换了就是复制到空的S0区域了逻辑还是和上面的一样,元空间是为了保存class/method/filed等等Java的垃圾回收Garbage Collection, GC是JVM自动管理内存的核心机制它负责回收程序中不再使用的对象所占用的内存。其中新生代Young Generation的回收Young GC/Minor GC是最频繁发生的GC事件理解其工作原理对于性能调优至关重要。2. 堆内存结构在HotSpot JVM中堆内存通常被划分为以下几个区域新生代 (Young Generation)存放新创建的对象。生命周期短GC频繁。Eden区 (Eden Space)新对象诞生的地方。幸存者区 (Survivor Space)分为两个大小相等的区域S0 (From Survivor) 和 S1 (To Survivor)。用于存放经过一次GC后存活下来的对象。老年代 (Old Generation/Tenured Generation)存放经过多次GC后依然存活的对象即“长寿”对象。GC频率较低但每次回收耗时更长。元空间 (Metaspace)在JDK 8及以后取代了永久代PermGen。主要用于存储类的元数据如类结构、方法、字段、常量池等信息。其内存不在堆内由本地内存管理。graph TD A[Java Heap] -- B[新生代 Young Generation] A -- C[老年代 Old Generation] A -- D[元空间 Metaspacebr/非堆内存] B -- E[Eden区 Eden Space] B -- F[幸存者区 Survivor Space] F -- F0[S0 (From)] F -- F1[S1 (To)]3. 新生代GCYoung GC详细流程3.1 初始状态与触发对象分配绝大多数通过new关键字创建的对象会首先被分配在Eden区。触发条件当Eden区被填满时便会触发一次Young GC也称为 Minor GC。3.2 复制与清除Copying Scavenging这是Young GC的核心采用“复制-清除”算法。存活对象标记GC线程会暂停所有应用线程Stop-The-World然后标记出Eden区和当前活动的Survivor区假设是S0中所有仍然存活的对象。初次GC时S0通常是空的。复制到空Survivor区将所有存活的对象一次性复制到另一个空闲的Survivor区假设是S1。年龄计数每经历一次Young GC并存活下来对象的“年龄”就会增加1岁。清空原区域将Eden区和刚才使用的S0区全部清空。此时S1区存放着本次GC后所有存活的新生代对象S0变为空闲。flowchart TD Start[Young GC 触发] -- A{Eden S0 (From) 已满?} A -- 是 -- B[标记 Eden S0 中的存活对象] B -- C[将所有存活对象复制到 S1 (To)] C -- D{S1 空间充足?} D -- 是 -- E[清空 Eden 和 S0] E -- F[交换 S0/S1 角色br/S1成为新的From, S0成为新的To] F -- End[Young GC 结束] D -- 否 -- G[触发对象晋升判断]3.3 对象晋升Promotion机制当存活对象过多目标Survivor区S1空间不足时便会触发对象向老年代的晋升。晋升规则是保障堆内存稳定的关键年龄阈值晋升JVM有一个阈值-XX:MaxTenuringThreshold默认15。如果存活对象的年龄达到或超过此阈值则优先将其晋升到老年代。分配担保晋升如果晋升了“老年”对象后S1区仍然空间不足JVM会尝试将剩余对象中年龄较大的也晋升到老年代。强制晋升如果经过上述步骤S1区依然无法容纳剩余对象则本次GC中所有存活的新生代对象都将被直接晋升到老年代。这是一种“兜底”策略。执行清空完成晋升后最后清空Eden区和S0区。简单来说晋升顺序是老的 - 半老的 - 如果还不行全部晋升。3.4 角色交换一次Young GC结束后两个Survivor区的角色会发生交换刚才存放存活对象的S1区在下次GC时将作为“From Survivor”。被清空的S0区在下次GC时将作为“To Survivor”准备接收新的存活对象。如此循环往复使得总有一个Survivor区是空的为下一次复制算法做好准备。4. 元空间Metaspace的作用元空间用于保存class/method/field等信息它与GC的关系主要体现在存储内容类的元数据、方法代码、常量池、注解等。内存回收当对应的类加载器ClassLoader被垃圾回收时其加载的类在元空间中的元数据才会被回收。因此元空间的GC通常发生在Full GC期间且与堆内存的Young/Old GC是相对独立的。好处避免了永久代时代的java.lang.OutOfMemoryError: PermGen space错误内存分配更灵活。5. 老年代GC与Full GC5.1 老年代GCMajor GC/Old GC当对象从新生代晋升到老年代或大对象直接分配在老年代时老年代空间会逐渐被占用。老年代GC的触发条件与新生代不同触发条件空间不足老年代自身空间不足时触发。晋升失败Young GC时存活对象需要晋升到老年代但老年代剩余空间不足。显式调用程序调用System.gc()建议JVM进行Full GC不保证立即执行。元空间/永久代空间不足JDK 7及之前。回收算法标记-清除Mark-Sweep先标记所有存活对象然后清除未标记的垃圾对象。会产生内存碎片。标记-整理Mark-Compact标记存活对象后将所有存活对象向一端移动然后清理边界外的内存。避免碎片但耗时更长。分代收集GenerationalHotSpot JVM默认采用分代收集策略针对老年代使用“标记-清除”或“标记-整理”算法。特点停顿时间长Stop-The-World老年代GC通常涉及全堆扫描暂停时间远长于Young GC。频率低对象在老年代存活时间长GC频率较低。吞吐量与延迟的权衡不同的GC器如Parallel GC、CMS、G1、ZGC对老年代回收策略不同需要在吞吐量和延迟之间取舍。5.2 Full GC整堆回收Full GC是指同时回收新生代、老年代以及方法区/元空间的全局垃圾回收。它是JVM中最耗时的GC操作。触发条件老年代空间不足且无法通过Young GC释放足够空间。方法区/元空间空间不足。调用System.gc()可能触发Full GC。某些GC器的自身策略如CMS并发失败后的后备方案。执行过程暂停所有应用线程Stop-The-World。标记整个堆包括新生代、老年代以及方法区/元空间中的存活对象。清除所有未标记的垃圾对象。整理内存取决于GC器以减少碎片。恢复应用线程。影响与优化长时间停顿Full GC可能导致应用停顿数秒甚至数十秒对延迟敏感的应用是灾难性的。优化方向减少对象晋升通过调整-XX:MaxTenuringThreshold、增大Survivor区避免过早晋升。增大堆内存提供更多缓冲空间。选择合适的GC器如G1、ZGC、Shenandoah等低延迟GC器能大幅减少Full GC的频率和停顿时间。5.3 常见GC器对老年代/Full GC的处理GC器老年代回收方式Full GC触发条件特点Serial GC单线程标记-整理老年代满、晋升失败等简单停顿长适合客户端应用Parallel GC吞吐量优先多线程标记-整理同Serial GC但并行处理高吞吐量停顿仍较长CMSConcurrent Mark Sweep并发标记-清除并发模式失败、晋升失败等低停顿但会产生碎片可能触发Full GC整理G1Garbage-First分区回收优先回收垃圾最多区域并发回收跟不上分配速度时可预测停顿兼顾吞吐与延迟ZGC并发标记-整理几乎无Full GC极少数情况亚毫秒级停顿适用于大内存5.4 监控与调优建议监控指标GC频率Young GC、Full GC的次数/频率。GC耗时各阶段停顿时间。内存占用各代使用率、晋升速率。常见参数-XX:UseConcMarkSweepGC启用CMS。-XX:UseG1GC启用G1。-XX:MaxGCPauseMillis目标最大停顿时间G1/ZGC。-XX:InitiatingHeapOccupancyPercent触发并发GC的堆占用阈值。调优思路避免频繁Full GC增大堆、调整新生代/老年代比例、选择低延迟GC器。减少晋升优化对象生命周期让短期对象在Young GC时就被回收。分析GC日志使用-Xlog:gc*或-XX:PrintGCDetails输出详细日志借助工具如GCeasy、GCE Viewer可视化分析。6. 总结与要点回顾更新关键点说明对象出生地Eden区Young GC触发Eden区满Young GC算法复制算法Eden From Survivor → To Survivor对象年龄每熬过一次Young GC年龄1晋升条件1. 年龄超阈值2. To Survivor区空间不足3. 分配担保失败Survivor区两个永远一存一空角色每次GC后互换老年代GC触发老年代空间不足、晋升失败等老年代GC算法标记-清除、标记-整理取决于GC器Full GC整堆回收停顿最长应尽量避免元空间存类元数据GC独立于堆GC器选择Serial/Parallel/CMS/G1/ZGC根据吞吐、延迟需求选择理解完整的GC流程Young GC → 对象晋升 → 老年代GC/Full GC能帮助我们优化代码减少短命大对象创建避免内存泄漏。合理配置JVM参数根据应用特点选择GC器、调整各代大小、设置停顿目标。分析GC日志定位是频繁Young GC、过早晋升还是老年代瓶颈从而针对性调优。关键点说明对象出生地Eden区GC触发Eden区满核心算法复制算法Eden From Survivor → To Survivor对象年龄每熬过一次Young GC年龄1晋升条件1. 年龄超阈值2. To Survivor区空间不足3. 分配担保失败Survivor区两个永远一存一空角色每次GC后互换元空间存类元数据GC独立于堆理解Young GC的流程有助于我们优化代码减少短命大对象的创建减轻GC压力。合理配置JVM参数如-Xmn(新生代大小)、-XX:SurvivorRatio(Eden与Survivor比例)、-XX:MaxTenuringThreshold(晋升年龄)。分析GC日志能快速定位是频繁Young GC还是晋升导致的老年代问题。您的理解抓住了核心流程本文在此基础上进行了系统化的梳理、补充了细节如年龄阈值、分配担保和可视化说明使其成为一篇完整的入门指南。

相关新闻

Claude Code 的 context window,真正决定一次长会话能走多远的隐形内存

Claude Code 的 context window,真正决定一次长会话能走多远的隐形内存

今天讨论 Claude Code 的 context window,比单纯讨论模型参数更有价值。很多开发者第一次用 Claude Code 时,会把它理解成一个更聪明的终端助手,能读代码、改文件、跑测试、解释报错。但真正跑过一段长会话后,体验会很快变成另一件事,我们不是在问 Claude Code 会不会写代…

2026/7/2 11:10:07阅读更多 →
400G网卡落地实践 哪些场景真正需要它

400G网卡落地实践 哪些场景真正需要它

400G网卡的价格摆在那里——一张双口400G网卡的价格,够买十几张25G网卡。很多IT负责人在采购时会犹豫:花了这笔钱,业务真的能跑满带宽吗?现实情况是,大量数据中心的服务器网卡利用率不到30%,有些甚至长期跑…

2026/7/2 11:10:07阅读更多 →
面向企业选型的线下销售会话分析实施指南:主流硬件解决方案深度评估

面向企业选型的线下销售会话分析实施指南:主流硬件解决方案深度评估

线下门店每天都在发生大量接待、沟通和成交动作,但这些过程往往像一个黑盒——管理者只能看到最终的到店数和成交率,却很难还原每一次接待中销售说了什么、客户关心什么、SOP有没有被执行到位。 2026年,越来越多企业意识到,只看结…

2026/7/2 11:10:07阅读更多 →
基于memuc与Appium的逍遥模拟器自动化测试全流程实战

基于memuc与Appium的逍遥模拟器自动化测试全流程实战

1. 项目概述:为什么是逍遥模拟器与memuc?在移动应用自动化测试的领域里,选择一个稳定、高效且易于控制的安卓模拟器,往往是项目成功的第一步。真机固然真实,但批量管理、环境隔离和快速回滚的需求,让模拟器…

2026/7/2 12:30:22阅读更多 →
Bugbug:无代码UI自动化测试工具,重塑敏捷开发质量保障

Bugbug:无代码UI自动化测试工具,重塑敏捷开发质量保障

1. 项目概述:当UI测试遇上“Bugbug”,一场效率革命在软件开发的日常里,UI测试和质量保证(QA)常常是那个“甜蜜的负担”。说它甜蜜,是因为一个稳定、流畅的用户界面是产品口碑的基石;说它是负担&…

2026/7/2 12:30:22阅读更多 →
支付系统性能压测实战:从JMeter脚本到瓶颈调优全解析

支付系统性能压测实战:从JMeter脚本到瓶颈调优全解析

1. 项目概述:为什么支付系统的性能测试是“生死线”?在金融科技领域,支付系统从来都不是一个简单的“功能”,它更像是一个数字经济的“心脏”。每一次点击支付,背后都是一次对系统处理能力、稳定性和准确性的极限考验。…

2026/7/2 12:30:22阅读更多 →
Parsec VDD虚拟显示器解决方案:Windows高性能显示虚拟化架构深度解析

Parsec VDD虚拟显示器解决方案:Windows高性能显示虚拟化架构深度解析

Parsec VDD虚拟显示器解决方案:Windows高性能显示虚拟化架构深度解析 【免费下载链接】parsec-vdd ✨ Perfect virtual display for game streaming 项目地址: https://gitcode.com/gh_mirrors/pa/parsec-vdd Parsec VDD(Virtual Display Driver&…

2026/7/2 12:30:22阅读更多 →
如何用DriverStoreExplorer解决C盘空间不足问题:3步清理Windows驱动垃圾

如何用DriverStoreExplorer解决C盘空间不足问题:3步清理Windows驱动垃圾

如何用DriverStoreExplorer解决C盘空间不足问题:3步清理Windows驱动垃圾 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer Windows系统用久了,C盘空间莫名其妙减少…

2026/7/2 12:30:22阅读更多 →
别让 AI Agent 变成黑盒:从 Tool Call 开始做审计日志

别让 AI Agent 变成黑盒:从 Tool Call 开始做审计日志

AI Agent 正在从“对话助手”变成“执行系统”。它不只生成文本,还会调用工具、访问接口、读写文件、触发业务流程。 当 Agent 开始执行真实动作后,我们就需要一套审计日志,回答一个最基础的问题:它到底做了什么?1. 什…

2026/7/2 12:25:21阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/2 12:10:34阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/2 12:10:34阅读更多 →
塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧 【免费下载链接】BOTW-Save-Editor-GUI A Work in Progress Save Editor for BOTW 项目地址: https://gitcode.com/gh_mirrors/bo/BOTW-Save-Editor-GUI 想在《塞尔达传说:旷野之息…

2026/7/2 0:03:01阅读更多 →
告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

在本地开发环境使用云厂商 CLI 时,传统的 AccessKey(AK)方式需要手动创建、下载和保管密钥,不仅繁琐,还存在泄漏风险。其实,主流云平台都已提供基于 OAuth 2.0 的免密认证方案,让开发者可以通过浏览器登录一次性完成授权,CLI 自动管理临时凭证的刷新,兼顾了便利与安全…

2026/7/2 0:03:01阅读更多 →
基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

1. 项目背景与核心价值在嵌入式系统开发领域,高精度定位与导航一直是极具挑战性的技术方向。传统方案往往面临成本、精度和实时性难以兼顾的困境。这个项目通过13DOF(13自由度)传感器组合与PIC32MZ2048EFH100高性能MCU的协同工作,…

2026/7/2 0:03:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/2 0:33:58阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/2 1:32:11阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/2 1:50:13阅读更多 →