JVM 的垃圾处理机制

JVM 的垃圾处理机制

一、垃圾回收的流程

JVM 的垃圾回收(Garbage Collection, GC)大体分为两步:

  1. 可达性分析(找到谁是垃圾)
  2. 垃圾回收算法(使用合适的算法处理垃圾)

二、可达性分析

可达性分析用来判断一个对象是否还存活。

JVM 会从一些 GC Roots(如虚拟机栈中的局部变量、方法区的静态变量、本地方法栈中的引用等)开始向外搜索,如果能通过引用链找到某个对象,那么该对象就是"可达"的,不会被回收;反之,就是"垃圾"。

需要注意:对象被标记为垃圾后,并不会立刻清除,而是等到下一次触发 GC 时才会被统一清理。


三、垃圾回收算法

常见的 GC 基础算法有三种:

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

    • 过程:先标记所有存活对象,再清理未标记的垃圾对象。
    • 缺点:会产生 内存碎片
  2. 复制(Copying)

    • 过程:将存活对象复制到另一块内存区域,清空原区域。
    • 优点:速度快,没有碎片。
    • 缺点:理论上浪费一半空间。
    • 实际 JVM 中,新生代采用 Eden + 两个 Survivor 区(常见比例 8:1:1),大大提高了利用率。
  3. 标记-整理(Mark-Compact)

    • 过程:标记存活对象后,将它们移动到一边,保持内存连续,再清理边界之外的垃圾。
    • 优点:解决碎片问题。
    • 缺点:移动对象需要额外开销。

四、分代收集

不同算法各有优劣,JVM 采用 分代收集(Generational GC) 的思想:

  • 新生代

    • 大多数对象朝生夕死。
    • 使用 复制算法,快速回收。
    • 新生代进一步划分为 1 个 Eden 区2 个 Survivor 区
    • 对象先分配在 Eden,经过多次 Minor GC 存活下来的对象晋升到老年代。
  • 老年代

    • 存放生命周期较长的对象。
    • 使用 标记-整理算法(或标记-清除 + 整理)。
    • 避免来回复制带来的性能损耗。
  • 大对象

    • 一些特别大的对象可能会直接分配到老年代,避免在新生代中频繁复制。

五、现代 GC 收集器

在实际 JVM 中,基础算法往往会被组合和优化,形成不同的收集器:

1. Serial GC

  • 特点:单线程,GC 时 Stop-The-World。
  • 算法:新生代用复制算法,老年代用标记-整理。
  • 适用场景:小应用、单核 CPU。

2. Parallel GC(吞吐量优先)

  • 特点:多线程并行回收,追求吞吐量最大化。
  • 适用场景:后台计算、大数据处理。
  • 缺点:GC 停顿仍然较长。

3. CMS(Concurrent Mark-Sweep)

  • 特点:并发标记和清除,减少停顿时间。
  • 算法:基于标记-清除。
  • 优点:适合对延迟敏感的应用(如 Web 服务)。
  • 缺点:会产生内存碎片,吞吐量低于 Parallel GC;在 JDK 9 起被标记为废弃。

4. G1(Garbage-First)

  • 特点:目前主流,JDK 9 之后默认收集器。
  • 设计:堆被划分为多个 Region,每次优先回收垃圾最多的 Region。
  • 优点 :兼顾吞吐量和低延迟,可预测停顿时间(如 -XX:MaxGCPauseMillis=200)。
  • 算法:新生代 → 复制;老年代 → 标记-整理。

5. 其他新一代收集器

  • ZGC(JDK 11+):超低延迟,GC 停顿 < 10ms,支持 TB 级堆。
  • Shenandoah(JDK 12+):与 ZGC 类似,低延迟 GC。

六、小结

  • 新生代:复制算法(快速回收,大部分对象很快死亡)。
  • 老年代:标记-整理(减少碎片,适合长期对象)。
  • 常见收集器
    • 小应用:Serial GC
    • 吞吐量优先:Parallel GC
    • 低延迟:CMS(逐渐淘汰)、G1(主流)
    • 超大堆/超低延迟:ZGC、Shenandoah
相关推荐
NEFU AB-IN4 小时前
Prompt Gen Desktop 管理和迭代你的 Prompt!
java·jvm·prompt
唐古乌梁海9 小时前
【Java】JVM 内存区域划分
java·开发语言·jvm
众俗10 小时前
JVM整理
jvm
echoyu.10 小时前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股
代码栈上的思考1 天前
JVM中内存管理的策略
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之进阶部分
jvm
沐浴露z1 天前
【JVM】详解 线程与协程
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之实战部分
jvm
程序员卷卷狗3 天前
JVM 调优实战:从线上问题复盘到精细化内存治理
java·开发语言·jvm
Sincerelyplz3 天前
【JDK新特性】分代ZGC到底做了哪些优化?
java·jvm·后端