源本科技 | 码上会

Java 垃圾回收

2026/01/23
40
0

学习目标

  • 理解垃圾回收的基本原理及其在内存管理中的重要性

  • 掌握对象的可达性概念及如何使对象成为垃圾回收的候选者

  • 了解不同的垃圾回收活动类型,包括 Minor GC 和 Major GC 的区别

  • 学会使用 Cleaner API 替代过时的 finalize() 方法进行资源清理

  • 明白垃圾回收的优势与潜在性能影响


核心概念

Java 中的垃圾回收(Garbage Collection, GC)是一种自动化的内存管理机制,它帮助 Java 程序高效运行。GC 主要负责从堆内存中移除不再使用的对象,从而释放被这些对象占用的内存空间。

对象存储位置

  • 堆内存:所有通过 new 关键字创建的对象都分配在堆上。

  • 当某些对象不再被程序需要时,它们将成为垃圾回收的目标。

垃圾回收工作流程

  1. 识别可达对象和不可达对象:GC 会检查哪些对象仍被引用(可达),哪些已不再被任何地方引用(不可达)。

  2. 移除不可达对象:一旦确定对象不可达,GC 就会将其从堆中清除。

注意:程序员无需手动标记待删除的对象;此过程由 JVM 内部实现。


垃圾回收活动类型

Java 堆被划分为多个世代:

  • 新生代(Young Generation):用于新创建的对象。

  • 老年代(Old Generation):存放长期存活的对象。

常见的两种垃圾回收活动包括:

  • Minor GC / 增量式垃圾回收:针对新生代中未被引用的对象进行清理。

  • Major GC / Full GC:处理那些经过 Minor GC 后仍然存活但最终变为不可达的老年代对象。此类回收发生的频率低于 Minor GC。


关键概念

1. 不可达对象

当一个对象没有任何引用指向它时,该对象即为不可达状态。

Integer i = new Integer(4); // 'i' 指向堆上的 Integer 对象
i = null; // 此时 Integer 对象变为不可达

2. 使对象适合回收

尽管开发者不必直接销毁无用对象,但在对象不再需要时,应尽量使其变得不可达(从而符合垃圾回收条件)。以下是几种常见方式:

  • 设置引用变量为 null

  • 重新赋值引用变量

  • 在方法内部创建的对象,在方法执行完毕后自动符合条件

  • “孤立岛”现象:对象之间相互引用但与外界隔离

3. 请求垃圾回收

虽然可以请求 JVM 执行垃圾回收,但这并不保证立即执行。有两种常用方式请求 GC:

  • 使用 System.gc()

  • 调用 Runtime.getRuntime().gc()

4. finalize() 方法

自 Java 9 起废弃

在对象被销毁前,GC 可能调用 finalize() 方法执行清理操作。然而,由于其不可预测性和可能引起的性能问题,自 Java 9 开始,推荐使用替代方案如 try-with-resources 或显式的清理方法。


思考题

  1. 为什么在实际开发中建议避免频繁调用 System.gc()

  2. Cleaner API 相比于传统的 finalize() 方法有哪些优势?

  3. 如果你的应用程序依赖于精确控制对象的销毁时机,你会选择哪种策略?为什么?