温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java老年代如何回收

发布时间:2026-10-08 18:33:38 来源:亿速云 阅读:102 作者:小樊 栏目:编程语言

在 Java(以 HotSpot 虚拟机为例) 中,老年代(Old Generation)的回收主要依靠 Major GC / Full GC,具体机制和算法取决于使用的垃圾收集器。下面系统地说明。


一、老年代是什么样的?

  • 存放 存活时间较长的对象
  • 对象来源:
    • 新生代 Minor GC 后存活的对象,年龄达到阈值(默认 15)
    • 大对象直接进入老年代
  • 老年代空间大、对象多,回收频率低但成本高

二、老年代垃圾如何判定?

老年代 不能使用简单的引用计数,而是依赖:

1. 可达性分析(GC Roots)

  • 从 GC Roots(栈、静态变量、JNI 等)出发
  • 不可达对象 = 垃圾

三、老年代常见回收算法

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

  • 步骤:
    1. 标记存活对象
    2. 清除未标记对象
  • 缺点:
    • 产生 内存碎片
  • 代表:CMS 的老年代

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

  • 步骤:
    1. 标记存活对象
    2. 向一端移动
    3. 清理边界外内存
  • 优点:
    • 无碎片
  • 缺点:
    • 移动对象成本高
  • 代表:Serial Old、Parallel Old

3. 复制算法(较少用于老年代)

  • 老年代一般 不用复制算法
  • 例外:G1 的 Region 混合回收

四、不同垃圾收集器的老年代回收

1. Serial GC(串行)

  • 老年代:Serial Old
  • 算法:Mark-Compact
  • 单线程,Stop The World

2. Parallel GC(并行)

  • 老年代:Parallel Old
  • 算法:Mark-Compact
  • 多线程,吞吐优先

3. CMS(Concurrent Mark Sweep)

老年代流程:

  1. 初始标记(STW)
  2. 并发标记
  3. 重新标记(STW)
  4. 并发清除

特点:

  • 低停顿
  • 碎片问题严重
  • JDK 9 弃用,JDK 14 移除

4. G1(Garbage First)

  • 老年代 + 新生代统一分 Region
  • 老年代回收在 Mixed GC 中完成
  • 算法:Mark-Compact(局部)
  • 可预测停顿

5. ZGC / Shenandoah

  • 几乎全并发
  • 老年代无明确区分
  • 极低停顿(< 10ms)

五、什么会触发老年代回收?

常见触发条件:

  • 老年代空间不足
  • Minor GC 晋升失败
  • 显式 System.gc()(不推荐)
  • Metaspace 不足(Full GC)
  • CMS 并发失败

六、Full GC vs Major GC

  • Major GC:只回收老年代
  • Full GC:老年代 + 新生代 + 元空间

实际中 Major GC 常伴随 Full GC


七、老年代回收优化建议

  1. 合理设置堆大小
  2. 避免大对象频繁创建
  3. 控制对象晋升年龄
  4. 优先使用 G1 / ZGC
  5. 减少 Full GC 次数

如果你愿意,我可以:

  • 画一张 内存回收流程图
  • 针对 JDK 8 / JDK 17 给具体参数
  • 结合你的 GC 日志 分析问题

你用的是哪种 JDK 和 GC?

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手