Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

  • JVM

    • JVM概述
    • JVM基础

    • 类加载机制

    • 运行时内存

    • 垃圾回收

      • 垃圾回收概述
      • 可达性分析与引用类型
      • 垃圾回收算法
        • 1. 标记-清除算法
        • 2. 标记-复制算法
        • 3. 标记-整理算法
        • 4. 分代收集
        • 5. 分区收集
        • 6. 并发与并行
        • 7. 阶段小结
        • 8. 三大算法图解
          • 8.1 标记-清除
          • 8.2 标记-复制
          • 8.3 标记-整理
        • 9. 算法选择和对象存活率
        • 10. 并发标记的难点
        • 11. Tips 快问快答
      • 分代收集与对象晋升
      • 常见垃圾回收器
      • G1垃圾回收器
      • ZGC与低延迟GC
      • GC日志分析
    • 执行引擎与优化

    • 工具与问题排查

    • 调优实践与面试

目录

垃圾回收算法

垃圾回收算法决定了 JVM 如何回收无用对象。不同算法在速度、内存碎片、停顿时间和空间浪费之间有不同取舍。

# 1. 标记-清除算法

标记-清除分两步:

  1. 标记所有存活对象。
  2. 清除未被标记的对象。

优点:

  • 思路简单。
  • 不需要移动对象。

缺点:

  • 会产生内存碎片。
  • 清除后空闲空间不连续。
  • 分配大对象时可能失败。

# 2. 标记-复制算法

复制算法把内存分为两块,每次只使用其中一块。回收时把存活对象复制到另一块,然后一次性清空原区域。

优点:

  • 没有内存碎片。
  • 分配速度快。
  • 适合存活对象少的区域。

缺点:

  • 浪费一部分空间。
  • 存活对象多时复制成本高。

新生代中对象大多朝生夕死,因此复制算法很适合新生代。

# 3. 标记-整理算法

标记-整理分两步:

  1. 标记存活对象。
  2. 把存活对象向内存一端移动。

优点:

  • 没有内存碎片。
  • 不需要像复制算法那样预留等大空间。

缺点:

  • 移动对象成本较高。
  • 停顿时间可能较长。

老年代对象存活率高,更适合标记-整理思想。

# 4. 分代收集

分代收集基于一个经验事实:

大多数对象生命周期很短,少数对象生命周期很长。

因此堆可以分为:

  • 新生代:对象创建频繁,死亡率高。
  • 老年代:对象存活时间长,死亡率低。

不同区域使用不同回收策略,提高整体效率。

# 5. 分区收集

G1、ZGC 等现代收集器更强调分区思想。

堆被划分为多个 Region 或 Page,回收时可以选择部分区域,而不是每次都处理整个堆。

分区收集有助于:

  • 控制停顿时间。
  • 支持大堆。
  • 更灵活地安排回收优先级。

# 6. 并发与并行

并行和并发是 GC 中常见概念。

并行:

多个 GC 线程同时工作,用户线程暂停

并发:

GC 线程和用户线程同时工作

低延迟收集器通常尽量把更多工作并发化,减少 STW。

# 7. 阶段小结

GC 算法没有银弹。复制算法适合存活率低的区域,标记-整理适合存活率高的区域,分代和分区是现代 JVM 提升回收效率的重要思想。理解算法取舍,才能理解不同垃圾回收器的行为。

# 8. 三大算法图解

# 8.1 标记-清除

回收前:
[A][垃圾][B][垃圾][C][垃圾]

标记存活:
[A*][垃圾][B*][垃圾][C*][垃圾]

清除后:
[A][空][B][空][C][空]

问题是会产生碎片,后续大对象可能找不到连续空间。

# 8.2 标记-复制

From:
[A][垃圾][B][垃圾][C]

复制存活对象到 To:
To:
[A][B][C][空][空]

清空 From,交换 From/To

适合存活对象少的区域,比如新生代。

# 8.3 标记-整理

回收前:
[A][垃圾][B][垃圾][C]

整理后:
[A][B][C][空][空]

没有碎片,但移动对象和更新引用成本较高。

# 9. 算法选择和对象存活率

存活率 更适合的算法 原因
低 复制 只复制少量存活对象
高 标记-整理 复制大量对象成本太高
中等 分区/混合策略 根据区域收益选择

这就是为什么新生代和老年代通常采用不同策略。

# 10. 并发标记的难点

并发 GC 中,GC 线程和业务线程同时运行。问题是业务线程可能在标记过程中改变引用关系。

例如:

GC 正在标记
业务线程把 A.field 从 B 改成 C

如果没有额外机制,GC 可能漏标或错标对象。现代收集器会使用写屏障、读屏障、记忆集、SATB 等机制维护正确性。

# 11. Tips 快问快答

Q:为什么新生代常用复制算法?

A:因为新生代大多数对象很快死亡,存活对象少,复制成本低。

Q:标记-清除最大问题是什么?

A:内存碎片。碎片多时可能无法分配连续大对象。

Q:标记-整理为什么停顿可能长?

A:需要移动对象并更新引用,工作量较大。

Q:分代收集是算法吗?

A:更准确说是收集策略,它根据不同代的对象特点组合不同算法。

上次更新: 2026/06/24, 16:03:01
可达性分析与引用类型
分代收集与对象晋升

← 可达性分析与引用类型 分代收集与对象晋升→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式