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

JVM 中的垃圾回收算法及垃圾回收器详解

前言

Java 虚拟机(JVM)的自动内存管理机制中,垃圾回收(Garbage Collection, GC)是至关重要的一个环节。它不仅负责释放那些不再被使用的对象所占用的内存空间,还对程序的性能有着重要影响。本文将详细介绍 JVM 中的垃圾回收算法以及各个版本 JDK 对应的垃圾回收器,并探讨它们的工作原理和适用场景。


一、垃圾回收算法

1. 标记-清除(Mark-Sweep)

标记-清除是最基础的垃圾回收算法之一。其工作过程分为两个阶段:

  • 标记阶段:遍历所有对象引用,找出哪些对象是存活的。
  • 清除阶段:回收未被标记的对象所占用的空间。

优点

  • 实现简单,不需要额外空间。

缺点

  • 效率低,特别是在存在大量对象的情况下。
  • 容易产生内存碎片,导致后续大对象分配时出现空间不足的问题。

2. 复制(Copying)

复制算法将可用内存按容量划分为两块,每次只使用其中一块。当这一块内存用完时,就将存活的对象复制到另一块上面,然后把已使用的内存空间一次清理掉。

优点

  • 不会产生内存碎片。
  • 实现简单,运行高效。

缺点

  • 内存利用率低,因为需要预留一半的内存用于复制。

3. 标记-整理(Mark-Compact)

标记-整理结合了标记-清除和复制的优点。在标记阶段之后,不是直接清除未标记的对象,而是让所有存活的对象向一端移动,然后清理掉端边界以外的内存。

优点

  • 解决了内存碎片问题。
  • 提高了内存利用率。

缺点

  • 移动对象的成本较高。

4. 分代收集(Generational Collection)

现代垃圾回收器通常采用分代收集的思想,根据对象存活周期的不同将其划分成不同的区域进行回收。一般分为年轻代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,现已改为元空间 Metaspace)。年轻代又细分为 Eden 区和 Survivor 区(S0/S1)。

  • 年轻代:新创建的对象首先分配在这里,由于大部分对象生命周期较短,所以这里采用复制算法。
  • 老年代:经过几次垃圾回收后仍然存活的对象会被晋升到这里,采用标记-清除或标记-整理算法。
  • 元空间:存储类的元数据等信息,从 JDK8 开始,永久代被移除,改用本地内存实现的元空间替代。

二、垃圾回收器

随着 JDK 版本的发展,JVM 引入了多种垃圾回收器,每种都有其特定的应用场景和优化方向。

1. Serial 收集器

Serial 收集器是最基本的新生代垃圾收集器,单线程执行,适用于单核处理器或小型应用。

  • JDK 版本:自 JDK1.3 以来一直存在。
  • 特点:简单高效,适合于客户端模式下的应用。

2. Parallel/Throughput 收集器

Parallel 收集器也是一款针对新生代的收集器,但它可以使用多线程并行执行,提高了垃圾回收效率,适合于多核服务器环境。

  • JDK 版本:从 JDK6 开始成为默认的服务器端收集器。
  • 特点:追求高吞吐量,减少 GC 停顿时间。

3. CMS(Concurrent Mark Sweep)收集器

CMS 是一种以获取最短回收停顿时间为目标的老年代垃圾收集器,通过并发方式执行大部分工作,减少了应用程序的停顿时间。

  • JDK 版本:JDK5 引入,JDK9 中被标记为废弃。
  • 特点:低延迟,但可能会导致碎片化问题,且 CPU 资源消耗较大。

4. G1(Garbage First)收集器

G1 是面向服务端应用的垃圾收集器,旨在替代 CMS。它将堆划分为多个大小相等的独立区域(Region),跟踪每个 Region 里垃圾的数量,优先回收价值最大的 Region。

  • JDK 版本:JDK7u4 作为实验性功能推出,JDK9 成为默认收集器。
  • 特点:预测停顿时间模型,可配置最大停顿时间目标;减少了 Full GC 的发生频率。

5. ZGC(Z Garbage Collector)

ZGC 是一个可扩展的低延迟垃圾收集器,设计目标是在任意堆大小下都能提供不超过 10 毫秒的暂停时间。

  • JDK 版本:JDK11 作为实验特性引入,JDK15 正式发布。
  • 特点:非常低的停顿时间,支持非常大的堆(TB 级别)。

6. Shenandoah

Shenandoah 与 ZGC 类似,也是一个低暂停时间的垃圾收集器,但它是由 Red Hat 开发并贡献给 OpenJDK 项目的。

  • JDK 版本:JDK12 引入,JDK15 GA。
  • 特点:同样专注于降低 GC 停顿时间,具有更广泛的平台支持。

三、总结

选择合适的垃圾回收器对于提升应用性能至关重要。不同的应用场景可能需要不同类型的垃圾回收策略。例如,对于响应时间敏感的服务端应用,可能更适合使用 G1 或 ZGC;而对于后台批处理任务,则可能更倾向于使用 Parallel 收集器来最大化吞吐量。

随着 JDK 版本的不断演进,新的垃圾回收技术也在持续发展。开发者应密切关注这些变化,并根据实际需求调整自己的垃圾回收策略,以获得最佳的应用性能。希望这篇文章能帮助你更好地理解 JVM 中的垃圾回收机制及其背后的原理。如果你有任何疑问或者想要分享的经验,请在评论区留言!

http://www.lqws.cn/news/600841.html

相关文章:

  • JavaWeb笔记02
  • 渗透测试(Penetration Testing)入门:如何发现服务器漏洞
  • pcap流量包分析工具设计
  • 数据结构:递归:斐波那契数列(Fibonacci Sequence)
  • 05【C++ 入门基础】内联、auto、指针空值
  • 09异常处理
  • 设计模式(七)
  • 视频内存太大怎么压缩变小一点?视频压缩的常用方法
  • Bilibili多语言字幕翻译扩展:基于上下文的实时翻译方案设计
  • Cypher 是 Neo4j 专用的查询语言
  • nanoGPT复现——prepare拆解(自己构建词表 VS tiktoken)
  • Lombok 与 Jackson 注解详解(基础 + 深入)
  • day52-硬件学习之RTC及ADC
  • 从零实现在线OJ平台
  • Y-Combinator推导的Golang描述
  • Go语言的Map
  • 编写shell脚本扫描工具,扫描服务器开放了哪些端口(再尝试用python编写一个)
  • java web2(黑马)
  • 7.1_JAVA_其他
  • Excel
  • 【前端】vue工程环境配置
  • 洛谷P1379 八数码难题【A-star】
  • LangChain4j在Java企业应用中的实战指南-3
  • uniapp 中使用路由导航守卫,进行登录鉴权
  • css函数写个loading动画 | css预编译scss使用
  • MAC环境搭建SVN,并将TOMCAT集成到IDEA
  • 地震灾害的模拟
  • Springboot整合高德地图
  • filebeat收集日志到es
  • 大模型MCP技术之一句话安装Hadoop