理解垃圾回收的基本原理及其在内存管理中的重要性
掌握对象的可达性概念及如何使对象成为垃圾回收的候选者
了解不同的垃圾回收活动类型,包括 Minor GC 和 Major GC 的区别
学会使用 Cleaner API 替代过时的 finalize() 方法进行资源清理
明白垃圾回收的优势与潜在性能影响
Java 中的垃圾回收(Garbage Collection, GC)是一种自动化的内存管理机制,它帮助 Java 程序高效运行。GC 主要负责从堆内存中移除不再使用的对象,从而释放被这些对象占用的内存空间。
堆内存:所有通过 new 关键字创建的对象都分配在堆上。
当某些对象不再被程序需要时,它们将成为垃圾回收的目标。
识别可达对象和不可达对象:GC 会检查哪些对象仍被引用(可达),哪些已不再被任何地方引用(不可达)。
移除不可达对象:一旦确定对象不可达,GC 就会将其从堆中清除。
注意:程序员无需手动标记待删除的对象;此过程由 JVM 内部实现。
Java 堆被划分为多个世代:
新生代(Young Generation):用于新创建的对象。
老年代(Old Generation):存放长期存活的对象。
常见的两种垃圾回收活动包括:
Minor GC / 增量式垃圾回收:针对新生代中未被引用的对象进行清理。
Major GC / Full GC:处理那些经过 Minor GC 后仍然存活但最终变为不可达的老年代对象。此类回收发生的频率低于 Minor GC。
当一个对象没有任何引用指向它时,该对象即为不可达状态。
Integer i = new Integer(4); // 'i' 指向堆上的 Integer 对象
i = null; // 此时 Integer 对象变为不可达尽管开发者不必直接销毁无用对象,但在对象不再需要时,应尽量使其变得不可达(从而符合垃圾回收条件)。以下是几种常见方式:
设置引用变量为 null
重新赋值引用变量
在方法内部创建的对象,在方法执行完毕后自动符合条件
“孤立岛”现象:对象之间相互引用但与外界隔离
虽然可以请求 JVM 执行垃圾回收,但这并不保证立即执行。有两种常用方式请求 GC:
使用 System.gc()
调用 Runtime.getRuntime().gc()
finalize() 方法自 Java 9 起废弃
在对象被销毁前,GC 可能调用 finalize() 方法执行清理操作。然而,由于其不可预测性和可能引起的性能问题,自 Java 9 开始,推荐使用替代方案如 try-with-resources 或显式的清理方法。
为什么在实际开发中建议避免频繁调用 System.gc()?
Cleaner API 相比于传统的 finalize() 方法有哪些优势?
如果你的应用程序依赖于精确控制对象的销毁时机,你会选择哪种策略?为什么?