侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

解释Java中对象何时会被垃圾回收?

2025-12-12 / 0 评论 / 4 阅读

题目

解释Java中对象何时会被垃圾回收?

信息

  • 类型:问答
  • 难度:⭐

考点

垃圾回收条件,可达性分析,GC Roots

快速回答

Java对象在满足以下条件时会被垃圾回收:

  • 对象不再被任何强引用关联
  • GC Roots出发无法访问到该对象
  • 即使存在循环引用,只要整体不可达也会被回收

注意:调用System.gc()仅建议JVM回收,不保证立即执行。

解析

原理说明

Java垃圾回收的核心是可达性分析算法:从GC Roots对象作为起点,通过引用链遍历所有存活对象。未被遍历到的对象判定为可回收。GC Roots包括:

  • 虚拟机栈中引用的对象(当前方法局部变量)
  • 方法区中静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI引用的对象

代码示例

public class GCDemo {
    public static void main(String[] args) {
        // 对象obj1和obj2相互引用
        Object obj1 = new Object();
        Object obj2 = new Object();
        obj1 = obj2;
        obj2 = obj1;

        // 切断外部引用
        obj1 = null;
        obj2 = null;

        // 此时两个对象虽循环引用,但已不可达
        System.gc(); // 建议JVM执行GC(实际回收时机不确定)
    }
}

此代码演示:即使obj1和obj2存在循环引用,当切断它们与GC Roots的连接后,仍会被回收。

最佳实践

  • 及时置空引用:对不再使用的大对象显式赋null(如集合对象)
  • 避免使用finalize():该方法可能导致对象复活且执行时机不确定
  • 谨慎使用System.gc():多数场景无需手动触发,可能引发性能问题

常见错误

  • 误认为循环引用会导致内存泄漏(Java可达性分析可正确处理)
  • 过度依赖System.gc()强制回收(实际由JVM决定执行时机)
  • 在finalize()中复活对象导致不可预测行为

扩展知识

  • 引用类型:除强引用外,还有软引用(内存不足时回收)、弱引用(下次GC时回收)、虚引用(用于跟踪回收状态)
  • 垃圾回收器:Serial、Parallel、CMS、G1等不同实现,适用于不同场景
  • 触发条件:当新生代(Eden区)满时触发Minor GC,老年代满时触发Full GC