问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

JVM垃圾回收全攻略:标记清除、复制、整理及新一代收集器

创作时间:
作者:
@小白创作中心

JVM垃圾回收全攻略:标记清除、复制、整理及新一代收集器

引用
CSDN
1.
https://blog.csdn.net/i_YOLO/article/details/145765698

JVM垃圾回收机制是Java开发中一个非常重要且复杂的主题。本文将全面介绍JVM垃圾回收的基本原理、常见算法、分代收集策略以及现代垃圾收集器的实现方式,帮助开发者深入理解JVM内存管理机制。

JVM垃圾回收全攻略:标记清除、复制、整理及新一代收集器

一、垃圾回收的基本思想

JVM 的垃圾回收(Garbage Collection, GC)主要解决内存管理问题,自动回收不再被引用的对象,避免内存泄漏,同时降低开发者的内存管理负担。核心思想基于可达性分析,从 GC Roots(如栈中局部变量、静态属性、常驻线程等)出发,判定哪些对象是“活”的,其余均可回收。

二、常见的垃圾回收算法

1. 引用计数算法(Reference Counting)

  • 原理:
    每个对象维护一个引用计数器,当计数为 0 时说明对象不再被使用,从而回收内存。

  • 缺陷:

  • 不能解决循环引用问题(例如两个对象互相引用但外部无引用)。

  • 维护计数带来额外的性能开销。

  • 现状:
    现代 JVM 几乎不采用引用计数,而是使用可达性分析。

2. 可达性分析(Reachability Analysis)

  • 原理:
    从一系列被称为 GC Roots 的根节点出发,通过递归或迭代遍历整个对象图,标记出所有可达对象,未被标记的对象即为垃圾。

  • 优点:

  • 能正确处理循环引用问题。

  • 不需要维护额外的计数信息。

  • 应用:
    作为大部分垃圾收集器的基础技术。

3. 标记-清除(Mark-Sweep)算法

  • 过程:
  1. 标记阶段:遍历所有可达对象并打上标记。
  2. 清除阶段:扫描整个堆,回收未被标记的对象。
  • 缺陷:

  • 产生大量内存碎片,可能导致后续分配失败。

  • 清除阶段需要遍历整个堆,停顿时间较长。

  • 改进:
    随后出现了标记-整理算法,解决内存碎片问题。

4. 标记-整理(Mark-Compact)算法

  • 过程:
  1. 标记阶段:与标记-清除相似。
  2. 整理阶段:将存活对象移动到堆的一端,形成连续的空闲内存区域。
  • 优点:

  • 避免了内存碎片问题,便于大对象的分配。

  • 缺陷:

  • 移动对象需要更新引用,带来额外开销,可能引起较长停顿。

5. 复制算法(Copying)

  • 过程:
    将内存划分为两个区域(From 区和 To 区),只使用其中一块。当 GC 触发时,将存活对象复制到另一块区域,然后一次性清空当前区域。

  • 优点:

  • 无碎片问题,复制过程简单高效。

  • 缺陷:

  • 需要额外 50% 的内存空间,适合对象存活率低的区域。

  • 应用:
    主要用于新生代垃圾回收,因为新创建的对象存活率低,复制开销较小。

6. 分代收集策略(Generational Collection)

JVM 根据对象存活周期的不同,将堆划分为不同的区域,分别采用适合的垃圾收集算法:

(1)新生代(Young Generation)

  • 特点:

  • 大部分对象生命周期短暂。

  • 使用复制算法(Eden 区与两个 Survivor 区交替使用)。

  • 过程:

  • 对象首先分配在 Eden 区,经过几次 Minor GC 后,存活对象在 Survivor 区之间复制;达到一定年龄后晋升到老年代。

(2)老年代(Old Generation)

  • 特点:

  • 存放生命周期较长的对象。

  • 使用标记-整理或标记-清除算法。

  • 注意:

  • 因为老年代对象较多,Full GC 时可能会有较长停顿。

(3)元空间/永久代(Metaspace/PermGen)

  • 功能:

  • 存放类信息、常量池、方法区数据。

  • 演进:

  • JDK 8 之前使用永久代(PermGen),JDK 8 之后改为元空间(Metaspace),避免了固定大小的问题。

7. 现代垃圾收集器

(1)CMS(Concurrent Mark-Sweep)

  • 特点:

  • 采用并发标记和清除,尽量缩短 STW(Stop The World)时间。

  • 不整理内存,可能会导致碎片化。

  • 适用场景:

  • 需要低停顿时间的应用,但对内存碎片较为宽容。

(2)G1(Garbage First)

  • 特点:

  • 将堆划分为多个大小相等的区域(Region),不再区分新生代和老年代的固定空间。

  • 采用混合回收策略,根据区域回收收益排序,优先回收垃圾最多的区域,从而达到低停顿与高吞吐量的平衡。

  • 优势:

  • 更好地控制 GC 停顿时间,适用于大内存场景。

  • 内部机制:

  • 包括初始标记、并发标记、重新标记和最终清除阶段,部分阶段仍是 STW,但时间可控。

(3)低延迟收集器:ZGC 与 Shenandoah

  • ZGC:

  • 适用于超大堆内存(TB 级别),目标是将停顿时间控制在毫秒级别。

  • Shenandoah:

  • 与 ZGC 类似,侧重于并发压缩和低停顿设计。

  • 特点:

  • 通过并发标记、并发整理和多种优化技术,实现低延迟和高吞吐量的平衡。

三、总结

  1. 基本原理:
    现代 JVM 垃圾回收的核心是从 GC Roots 开始的可达性分析,借助多种算法(标记-清除、复制、标记-整理等)来识别并回收垃圾对象。

  2. 分代收集:
    根据对象生命周期的特点,将堆分为新生代和老年代,新生代常采用复制算法,而老年代则使用标记-整理或标记-清除,以优化性能和降低停顿。

  3. 现代垃圾收集器:

  • CMS 和 G1通过并发和区域划分等技术降低 GC 停顿,适应大规模和高吞吐量场景;
  • ZGC 和 Shenandoah则专注于极低停顿,适合对延迟敏感的应用场景。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号