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. Survivor 区
        • 3. 对象年龄
        • 4. 老年代
        • 5. 大对象
        • 6. 空间分配担保
        • 7. G1 中的分代思想
        • 8. 阶段小结
        • 9. 新生代复制流程
        • 10. 动态年龄判断
        • 11. 晋升过快的排查方向
        • 12. Tips 快问快答
      • 常见垃圾回收器
      • G1垃圾回收器
      • ZGC与低延迟GC
      • GC日志分析
    • 执行引擎与优化

    • 工具与问题排查

    • 调优实践与面试

目录

分代收集与对象晋升

分代收集是 HotSpot JVM 长期使用的重要思想。它基于“多数对象很快死亡,少数对象长期存活”的经验规律。

# 1. 新生代

新生代通常存放新创建的对象。

传统布局:

Eden + Survivor From + Survivor To

对象优先在 Eden 分配。当 Eden 空间不足时触发 Young GC。

# 2. Survivor 区

Young GC 时,Eden 和一个 Survivor 区中的存活对象会被复制到另一个 Survivor 区。

Eden + From -> To

回收后,From 和 To 角色互换。

Survivor 区的意义是让短期存活对象有机会在新生代继续观察,而不是立刻进入老年代。

# 3. 对象年龄

对象每经历一次 Young GC 后仍然存活,年龄会增加。

当年龄达到阈值后,对象可能晋升到老年代。

相关参数:

-XX:MaxTenuringThreshold

实际晋升并不只看这个参数,还会受 Survivor 空间和动态年龄判断影响。

# 4. 老年代

老年代存放生命周期较长的对象。

对象进入老年代的常见原因:

  • 年龄达到晋升阈值。
  • Survivor 空间不足。
  • 大对象直接进入老年代。
  • 动态年龄判断触发晋升。

老年代回收通常比新生代成本更高,停顿也可能更明显。

# 5. 大对象

大对象是指需要大量连续内存的对象,例如大数组。

byte[] data = new byte[20 * 1024 * 1024];

大对象可能直接进入老年代,避免在新生代复制来复制去。

大对象频繁创建容易导致:

  • 老年代压力大。
  • 内存碎片。
  • Full GC。
  • 分配失败。

# 6. 空间分配担保

Young GC 前,JVM 需要判断老年代是否有足够空间容纳可能晋升的对象。

如果担保失败,可能提前触发老年代回收或 Full GC。

这就是为什么新生代回收也可能牵动老年代。

# 7. G1 中的分代思想

G1 使用 Region 管理堆,不再是连续的新生代和老年代。

但 G1 仍有分代概念:

  • Eden Region。
  • Survivor Region。
  • Old Region。

只是这些 Region 在物理上可以不连续。

# 8. 阶段小结

分代收集的核心是根据对象生命周期选择不同策略。新对象在 Eden 分配,存活对象进入 Survivor,多次存活后晋升老年代。理解对象晋升路径,有助于分析 Young GC、老年代增长和 Full GC。

# 9. 新生代复制流程

Young GC 前:
Eden: [A][垃圾][B][垃圾]
From: [C][垃圾]
To:   [空][空][空]

Young GC 后:
Eden: [空][空][空][空]
From: [空][空]
To:   [A age+1][B age+1][C age+1]

下一轮:
From 和 To 交换角色

每次 Young GC 后,存活对象年龄增加。如果达到晋升阈值,或 Survivor 放不下,就进入老年代。

# 10. 动态年龄判断

对象不一定非要达到 MaxTenuringThreshold 才晋升。

JVM 可能根据 Survivor 中相同年龄对象大小做动态判断:如果某个年龄及以上对象大小总和超过 Survivor 空间的一定比例,这些对象可能提前晋升。

这就是为什么有时明明设置了较高晋升年龄,对象还是很快进入老年代。

# 11. 晋升过快的排查方向

现象 可能原因
Young GC 后老年代明显增长 中生命周期对象多
Survivor 使用率很高 Survivor 太小或存活对象多
Full GC 变频繁 晋升速度超过老年代回收能力
大对象直接进老年代 数组、字符串、批量查询过大

优化方向:

  • 减少一次请求中的大对象。
  • 控制批量查询大小。
  • 避免大 JSON 一次性反序列化。
  • 调整新生代和 Survivor,但要基于日志。

# 12. Tips 快问快答

Q:对象年龄存在哪里?

A:HotSpot 中对象年龄信息存放在对象头 Mark Word 中的一部分位上。

Q:为什么 Survivor 有两个?

A:复制算法需要 From 和 To 两个区域,在 Young GC 时把存活对象复制到另一块。

Q:大对象为什么可能直接进老年代?

A:大对象复制成本高,也可能需要连续空间,因此 JVM 可能让它直接进入老年代或 Humongous Region。

Q:Young GC 会不会导致 Full GC?

A:可能。比如晋升担保失败、老年代空间不足等场景可能引发更重的回收。

上次更新: 2026/06/24, 16:03:01
垃圾回收算法
常见垃圾回收器

← 垃圾回收算法 常见垃圾回收器→

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