JVM垃圾回收器演进及方法区实现解析

JVM垃圾回收器全面解析:从核心概念到选型指南 JVM内存调优的本质是平衡吞吐量、延迟和内存占用三者关系。调优效果 = 数据驱动分析 × 合理参数调整 × 代码优化准确识别各内存区域的问题熟练使用JDK工具链进行诊断制定针对性的优化方案建立完整的调优方法论最后忠告:没有银弹参数,只有最适合业务的配置! 阅读详情

JVM垃圾回收器演进及方法区实现解析

在JVM的内存管理中,垃圾回收器的设计直接影响应用的性能表现,而方法区的实现则关系到内存分配的合理性与稳定性。结合实际探讨,我们可清晰梳理出垃圾回收器的演进逻辑、核心原理,以及方法区从永久代到元空间的迭代原因与优势,以下是详细解析。
在这里插入图片描述

一、JVM垃圾回收器的演进及核心区别

JVM垃圾回收器的发展核心的是围绕“缩短停顿时间、提升吞吐量、实现停顿可控”展开,从早期的Parallel GC,到CMS,再到G1,直至新一代的ZGC,每一代都针对前一代的不足进行了针对性优化,形成了清晰的演进脉络。

(一)Parallel GC:并行加速回收,仍有停顿局限

Parallel GC的核心设计思路是通过增多GC线程的数量,实现垃圾回收任务的并行执行,从而加速GC回收过程,提升应用吞吐量。无论是新生代还是老年代,Parallel GC都会启动多个GC线程协同工作——新生代采用复制算法时,多个GC线程同时复制存活对象;老年代采用标记-整理算法时,多个GC线程同时执行标记和压缩操作。

需要注意的是,Parallel GC的“并行”仅指多个GC线程之间的并行,在GC执行过程中,应用线程仍会处于完全停顿状态(STW,Stop The World)。其核心目标是通过缩短单次GC的STW时间、减少GC执行频率,让应用线程有更多时间运行,进而提高整体吞吐量,但无法解决应用线程停顿的根本问题。

(二)CMS:并发执行减少停顿,停顿仍不可控

CMS(Concurrent Mark Sweep)垃圾回收器的核心突破是实现了GC线程与应用线程的并发执行,从根本上减少了应用线程的停顿时间。与Parallel GC不同,CMS的“并发”是指GC线程在大部分时间里与应用线程同时运行,仅在标记的初始阶段和重新标记阶段会产生短暂的STW停顿,因此整体停顿时间远低于Parallel GC。

但CMS存在明显局限:虽然停顿时间大幅缩短,但停顿时间仍处于不可控状态,无法提前设定并保证停顿目标;同时,CMS采用标记-清除算法,会产生内存碎片,长期运行后可能因碎片过多导致Full GC,进而引发较长时间的停顿,影响应用稳定性。

(三)G1:分区回收+收益排序,实现停顿可控

G1(Garbage-First)垃圾回收器在设计上跳出了传统的新生代、老年代划分模式,通过Region(区域)将堆内存拆分为多个小的独立区域,每个Region可灵活充当新生代或老年代,实现了垃圾回收的局部化。

G1的核心优势的是“停顿时间可控”,其通过“垃圾优先”算法,对每个Region的回收收益(回收的内存量与所需时间的比值)进行计算,然后根据用户设定的停顿目标,选择收益最高的一批Region进行回收。这种设计让GC回收可以聚焦在小范围内,避免了对整个堆内存的全面扫描,从而主动控制停顿时间,解决了CMS停顿不可控的问题。但G1的停顿时间会随堆内存大小的增加而上升——堆越大,需要回收的Region数量越多,计算收益和处理区域的耗时也会增加,无法满足超大堆场景下的低延迟需求。

(四)ZGC:新一代低延迟回收器,突破堆大小限制

ZGC是JDK 11中引入的实验性垃圾回收器,在JDK 15时正式转正,是针对超大堆、低延迟场景设计的新一代回收器,其核心目标是实现亚毫秒级的GC停顿,且停顿时间不受堆大小影响,即使堆内存达到TB级别,停顿时间也能控制在10ms以内。

  1. 核心技术:染色指针与并发重分配

ZGC之所以能突破堆大小的限制,核心在于采用了染色指针和读屏障技术,同时实现了并发标记、并发重分配(对象移动)。染色指针本身是一个逻辑概念,通过在指针的高几位设置标记位,来表示对象的状态(如“已移动”“未移动”);而对象移动后的转发新地址,则是一个物理概念——当GC并发移动对象时,会将旧地址的标记位设为“已移动”,并在旧地址的内存空间中物理存储新地址。

  1. 地址重定向机制

当应用线程访问已移动的对象时,读屏障会检测到指针上的“已移动”标记,自动从旧地址中读取新地址,并将应用线程的指针更新为新地址,整个过程对应用线程透明且耗时极短。这种机制让对象移动的大部分工作能在应用线程运行时并发完成,STW阶段仅需执行少量必要操作,因此停顿时间几乎不随堆大小变化。

  1. 核心优势与解决的问题

ZGC解决了G1在超大堆场景下停顿时间上升的问题,同时也规避了CMS的内存碎片和停顿不可控问题。其核心优势是低延迟、支持超大堆,且能通过并发移动对象解决内存碎片问题。但ZGC的并发操作会带来一定的CPU开销,因此对于CPU资源紧张、更看重吞吐量而非延迟的场景,不如Parallel GC适用。

补充说明:ZGC的对象移动与传统回收器的区别——传统回收器(如G1)移动对象时,需要进入STW阶段,暂停所有应用线程,由GC线程复制对象并更新所有引用;而ZGC通过染色指针和读屏障,实现了对象移动与应用线程的并发执行,无需长时间STW,这也是其能保持极短停顿的根本原因。

二、方法区的实现演进:从永久代到元空间

方法区是JVM规范定义的逻辑区域,用于存储类信息、常量、静态变量、方法字节码等数据,而永久代和元空间,都是HotSpot虚拟机对方法区的具体物理实现,两者的迭代也体现了JVM内存管理的优化思路。

(一)永久代:JDK 8之前的方法区实现

在JDK 8之前,HotSpot虚拟机采用永久代作为方法区的物理实现,永久代存在于堆内存中,与新生代、老年代共存。此时堆内存的结构包括新生代(包含Eden区和两个Survivor区)、老年代和永久代,永久代的大小有固定限制,由JVM参数(如-XX:MaxPermSize)指定。

(二)元空间:JDK 8及以后的方法区实现

JDK 8中,永久代被彻底移除,堆内存仅保留新生代(Eden区、Survivor区)和老年代,方法区的实现改为元空间,元空间不再占用堆内存,而是直接使用本地内存(也称为堆外内存)。

(三)迭代原因、优势及解决的问题

  1. 解决永久代OOM问题:永久代有固定大小限制,当系统加载的类过多(如大量动态生成类、框架反射生成类)时,容易导致永久代内存溢出(java.lang.OutOfMemoryError: PermGen space)。元空间使用本地内存,其大小理论上受系统总内存限制,无需手动设置固定大小,从根本上避免了永久代OOM问题。

  2. 提升垃圾回收效率:永久代存在于堆内存中,GC回收时需要同时扫描堆中的新生代、老年代和永久代,范围较大,回收效率较低。移除永久代后,堆内存的GC范围仅集中在新生代和老年代,减少了GC的扫描范围,提升了堆内存的回收效率。

  3. 简化内存管理:元空间的内存管理更灵活,当类被卸载时,元空间占用的本地内存会直接归还给系统,无需像永久代那样依赖堆内存的GC回收,降低了内存管理的复杂度,也更符合JVM规范对方法区的定义(方法区应独立于堆内存)。

三、总结

JVM垃圾回收器的演进,是从“并行加速回收”(Parallel GC)到“并发减少停顿”(CMS),再到“停顿可控”(G1),最终实现“超大堆低延迟”(ZGC)的过程,每一步都针对前一代的局限,通过技术创新提升性能;而方法区从永久代到元空间的迭代,核心是解决内存溢出问题、提升回收效率、简化内存管理,让JVM的内存分配更灵活、更稳定。

不同的垃圾回收器和方法区实现,适用于不同的应用场景,理解其核心原理和区别,能帮助我们根据应用的性能需求(吞吐量、延迟、内存大小)选择合适的配置,优化应用的运行效率。

JVM与JMM深度解析:从Java 8到Java 21的演进 在Java开发者的职业生涯中,理解JVM(Java虚拟机)和JMM(Java内存模型)是进阶的必经之路。无论是日常开发还是面试,这都是绕不开的话题。本文将从实用角度出发,带你深入了解JVM和JMM的核心概念,并对比Java 8、Java 11、Java 17和Java 21各版本的实现差异,帮助大家更好的了解JVM和JMM 阅读详情

相关推荐

JVM垃圾回收器演进史:从单线程到亚毫秒停顿的探索之路

垃圾回收(Garbage Collection, GC)是Java生态的核心技术之一,其演进历程不仅反映了硬件性能的飞速发展,也映射了从桌面应用到云原生时代的场景变迁。本文将带你回顾JVM垃圾回收器的重要发展阶段,解析每个时代的关键技术及其背后的设计哲学。

正在努力模索的博客 766

JVM垃圾回收器

例如,在处理大量并发请求时,我们可以采用多线程或多进程的方式,将请求分发到不同的处理单元上,以提高系统的吞吐量和响应速度。例如,在G1回收器中,JVM会根据应用的实际运行情况,动态地调整各代的比例和垃圾回收的时机,以达到全局最优的效果。:Parallel回收器是Serial回收器的多线程版本,它利用多核CPU的优势,提高了垃圾回收的效率。JVM的垃圾回收器从最初的Serial回收器,发展到Parallel回收器、CMS回收器和G1回收器,经历了从单线程到并发与并行的转变。此外,我们还可以通过设置如。

guangzhi0633的专栏 1445

垃圾回收器(下)

G1(Garbage-First)是JVM中一种面向服务器端应用的垃圾回收器,自JDK 9起成为默认的垃圾回收器。它的设计目标是在可预测的停顿时间和高吞吐量之间取得平衡。

ckh20040422的博客 993

JVM方法区详解

方法区是《Java虚拟机规范》中定义的一个逻辑内存区域。它被所有Java虚拟机线程共享。可以把它想象成整个JVM的“信息中心”或“蓝图仓库它的主要作用是存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。简单来说,当写的.java文件被编译成.class文件,然后被JVM加载后,关于这个类的所有“元数据”(描述类的数据)都会被存放到方法区中。

牛马baby的博客 1641

ESP32Servo库驱动SG90舵机:从入门到精准控制

本文详细介绍了如何使用ESP32Servo库驱动SG90舵机,从硬件连接到软件环境搭建,再到编写示例程序实现精准控制。内容涵盖库安装、基础驱动代码解析、舵机校准方法以及平滑运动控制,帮助开发者快速掌握ESP32控制舵机的核心技能,并提供了电源管理、信号抗干扰等实用避坑指南。

ik678901的博客 901

uniapp原生安卓插件开发之路

声明: 我的功能需求:全局悬浮框,也就是在其他应用上依旧能悬浮。查遍uni文档,无法实现,甚至native.js也无法实现,无奈只能走上原生插件开发这条不归路了。(吐槽:天天写前端js,突然写了下android简直要炸,public static String啥的,var不香嘛,不过别人严谨肯定还是有别人道理的,加油吧,争取能入个门!) 本人不懂安卓开发,完全安卓小白,所以安卓方面可能表达的不是很好,安卓代码可能写的不优美,但我功能最终还是实现了。但是为了需求,能力总能被“逼”出来。有描述错误的还望指正

Jone's Area 1万+

JVM--9-深入JVM垃圾回收器:从Serial到ZGC的演进全景

优势缺点实现极简,内存开销极低(无并发线程开销,无额外数据结构)单线程回收,效率极低,大堆内存下停顿时间极长STW时间可预测(无并发干扰,每次GC停顿时间相对固定)全程STW,对应用响应性影响极大,无法满足高并发场景适合小堆内存(<4GB),回收效率尚可可扩展性差,多核心CPU环境下无法利用多核优势,资源浪费优势缺点充分利用多核 CPU,并行回收大幅提升吞吐全程STW,虽然停顿时间比Serial GC短,但仍无法满足低延迟场景。

weisian的博客 1万+

vasp计算练习1-Si

si的vasp训练流程

qq_41074165的博客 3302

JVM中的方法区

文章目录JVM中的方法区运行时数据区结构图栈堆方法区的交互关系方法区在哪里?方法区的基本理解Hotspot中方法区的演进设置方法区大小与OOMjdk7及以前:jdk8及以后:方法区的内部结构.class字节码文件中常量池方法区中的运行时常量池方法区在jdk6,jdk7,jdk8中的演进细节永久代为什么要被元空间替换?StringTable字符串常量池为什么要从永久代调整到堆中?静态变量存在哪?方法区的垃圾收集 JVM中的方法区 运行时数据区结构图 运行时数据区结构图,如下图: 从线程共享与否的角度来看,如

xzy的博客 2619

别再写爬虫了!用Trae平台5分钟搞定一个能聊天的网页数据抓取Agent

本文介绍了如何利用Trae平台快速构建无需编程的网页数据抓取智能体,实现对话式数据采集。通过自然语言指令,用户可在5分钟内完成从数据抓取到分析的全流程,显著降低技术门槛和维护成本。文章详细解析了Trae智能体的核心能力,包括自然语言理解、智能页面解析、数据清洗和可视化配置,并提供了多个实战案例,展示其在竞品监控和舆情分析中的高效应用。

weixin_29038303的博客 719

Fofa API高阶玩法:用Python批量获取漏洞资产(含OA系统扫描实战)

本文详细介绍了如何利用Python结合Fofa API实现自动化漏洞资产收集的高阶实战技巧。通过构建健壮的客户端、设计精准查询语法、实现多线程批量采集,并以OA系统漏洞扫描为例,演示了从资产发现、过滤验证到报告生成的全流程,旨在提升安全运维与应急响应的效率。

weixin_28607671的博客 501

从 Java 1 到 Java 25 的垃圾回收器演进与优化全解析

Java垃圾收集器演进历程:从Java 1的Serial单线程收集器起步,逐步引入Parallel、CMS等并发收集器。Java 7推出革命性的G1收集器(实验性),Java 9将其设为默认。后续版本持续优化,新增ZGC、Shenandoah等低延迟收集器,并引入分代式ZGC、弹性元空间等创新。每个版本都针对不同场景(吞吐量/低延迟)进行优化,反映了Java在性能调优上的持续进步。

wb04307201的博客 1532

用python提取PDF中各类文本内容的方法

用python提取PDF中各类文本内容的方法

安静的软件工程师 6089

JVM 新一代垃圾回收器实战指南

JVM 新一代垃圾回收器(ZGC、Shenandoah、G1)为我们提供了更多选择,让我们能够根据具体的业务场景选择最合适的 GC 策略。理解不同 GC 的特点和适用场景通过监控和日志分析 GC 行为根据实际负载进行针对性调优持续监控和优化记住,GC 调优是一个持续的过程,没有一劳永逸的方案。最重要的是理解原理,根据实际情况灵活调整,这其实可以更优雅一点。如果有任何问题或建议,欢迎在评论区留言,我会认真回复每一条评论。

alex_goden的博客 1932

即插即用系列(代码实践) | WACV 2024 CSAM:面向各向异性医学图像分割的 2.5D 跨切片注意力模块

文章摘要: 论文《CSAM: A 2.5D Cross-Slice Attention Module for Anisotropic Volumetric Medical Image Segmentation》提出了一种解决医学图像各向异性问题的创新模块CSAM。针对MRI/CT数据中切片间分辨率差异大的挑战,该模块通过2.5D跨切片注意力机制,结合2D卷积的轻量性和3D上下文感知能力。核心包括语义注意力(通道级)、位置注意力(空间级)和跨切片注意力(支持不确定性建模),能在几乎不增加参数量的情况下有效捕捉

分享顶会顶刊论文即插即用模块 107

导数与微分在 FPS 射击游戏中的实际应用:把“手感”算出来

摘要:射击游戏开发中,单线程适用于简单小游戏(如单机打靶),所有任务由主线程顺序处理,代码简单但效率较低;多线程则适合复杂场景(如多人在线3D大作),通过渲染、逻辑、网络、音效等线程分工协作,确保画面流畅、响应迅速和实时同步。选择依据取决于游戏复杂度、联网需求和性能要求,小型游戏用单线程,大型高要求项目必须采用多线程架构。(149字)

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 3279

深度学习与总结JVM专辑(七):垃圾回收器—CMS(图文+代码)

在Java虚拟机(JVM)的众多垃圾收集器(Garbage Collector, GC)中,CMS(Concurrent Mark Sweep)占有特殊的历史地位。虽然它在较新的JDK版本中已被标记为废弃(Deprecated)并最终移除,但理解CMS的设计理念、工作原理以及优缺点,对于深入掌握JVM内存管理、理解后续更先进的GC(如G1、ZGC)的演进思路,仍然具有非常重要的价值。CMS的核心目标是什么?简单来说,CMS的设计目标是获取尽可能短的回收停顿时间.

左灯右行的爱情 1985

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

方法区(Method Area)详解

1. 方法区的基本理解 1.1 栈,堆和方法区的关系 方法区可以看作是独立于Java堆的一部分,并且也是和堆一样是整个JVM实例共用一份。 1.2 方法区的基本理解 各个线程共享区域 在JVM启动时被创建,并且物理内存可以不连续 大小可以固定也可以是动态扩展的 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类会出现OOM错误。 会随着JVM的关闭而释放这一区域的内存 1.3 方法去的演进 在JDK 7以前,习惯上把方法区称为永久代(习惯上),而到了JDK8,终于..

qq_43684005的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JVM垃圾回收器全景解析:从Serial到ZGC的演进与对比

分代式ZGC(JDK21):年轻代独立回收,吞吐提升40%+NUMA优化:ZGC/Shenandoah适配非统一内存架构服务器GCaaS:云环境动态调整堆大小与回收策略Serial ─▶ Parallel ─▶ CMS ─▶ G1 ─▶ { ZGC ─▶ 分代模式,└─────────▶ Epsilon (测试旁路)每一代都是为了解决前者的瓶颈Serial → 利用多核 → ParallelParallel → 缩短停顿 → CMSCMS → 碎片 + 调优难 → G1。

weixin_44876263的博客 1160

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Java】JVM的垃圾回收器

垃圾回收机制是自动内存管理的核心技术,通过可达性分析识别不可访问的对象并回收其内存。现代垃圾回收器采用分代回收策略,将堆划分为年轻代和老年代,针对不同区域采用不同回收算法:年轻代使用高效的复制算法进行频繁Minor GC,而老年代则采用标记-清除或标记-整理算法进行较少但耗时的Full GC。主流回收器如CMS、G1和ZGC不断演进,从追求低延迟(CMS)到分区回收(G1),再到极致低停顿(ZGC),逐步解决了内存碎片、吞吐量与暂停时间之间的矛盾。分代设计和并发回收大幅提升了内存管理效率,使开发者从繁琐的手

m0_60524759的博客 905

JVM垃圾回收器和调优

十种垃圾回收器的简介以及调优的一些经验

dzyls的笔记 1万+

【无为】聊聊java中JVM的方法区

栈、堆、方法区的关系 方法区在哪里? https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4 《Java虚拟机规范》中明确说明: “尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。” 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap(非堆),目的就是要和堆分开。 所以,方法区看作是一块独立于Java 堆的内存空间。 方法区的理解 从

王傲旗的大数据之路 1774

jvm之【垃圾回收器】

代分工:新生代 / 老年代专用,或跨代(G1)。目标侧重:吞吐量优先(Parallel 系列)、低延迟(CMS、G1)、简单场景(Serial 系列)。并发能力:单线程(Serial)、多线程并行(ParNew、Parallel)、并发(CMS、G1)。实际应用中,需根据业务场景(如服务端低延迟 vs 后台批处理)选择搭配,G1 因 “可预测停顿” 和 “大内存适配”,逐渐成为主流替代方案。

weixin_62730133的博客 461

ZGC:Java低延迟垃圾回收器解析

在当今大数据和云计算时代,Java虚拟机(JVM)作为Java应用程序的运行环境,其性能和稳定性至关重要。然而,随着应用程序规模的不断扩大,传统的垃圾回收机制在处理大量数据时往往显得力不从心。特别是在内存密集型应用中,频繁的垃圾回收会导致系统性能下降,甚至出现内存溢出错误。为了解决这一问题,ZGC(Z Garbage Collector)应运而生。ZGC,全称为Z Garbage Collector,是JVM中的一种新型垃圾回收器。它旨在为大型Java应用程序提供低延迟和高吞吐量的垃圾回收性能。

JavaCodePro的博客 987

JVM中的垃圾回收算法和垃圾回收器

从根对象(如栈引用、静态变量等)出发,遍历所有可达对象并标记为 “存活”。:遍历整个内存区域,回收所有未被标记的对象(即垃圾),释放其占用的内存。实现简单,不需要移动对象。效率低,记和清除过程都需要遍历所有对象,耗时较长,尤其在对象数量多的时候。回收后会产生大量不连续的内存碎片,可能导致后续大对象无法分配内存(即使总空间足够)。

weixin_42294525的博客 1041
上一篇: Java(Spring AI)传统项目智能化改造——商业化真实案例(含完整核心代码+落地指南)
下一篇: Java高并发核心知识点完整总结
Coder_Boy_
博客等级 码龄10年 2804粉丝 819原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder_Boy_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值