返回

过早的给方法中引用对象设为null可被GC提前回收吗?实验揭秘真相!

后端

过早地给方法中的引用对象设为 null,可被GC 提前回收吗?#

前言

我们经常在代码中看到有人会将 null 赋值给引用类型,试图以此来达到让 GC 提前回收的目的。

那么,这样做真的有用吗?

今天我们就来研究一下这个问题。

实验

为了方便讲解,我们先来看一段测试代码:

public class GCTest {
    private Object test1 = new Object();
    private Object test2;

    public static void main(String[] args) {
        GCTest g = new GCTest();
        g.test1 = null;
        g = null;

        System.gc();

        // 尝试重新赋值 test1 变量
        // 如果被回收则会抛出异常
        g.test1 = new Object();
    }
}

这段代码中,我们先将 test1 变量设置为一个新的对象,然后将 test2 变量设置为 null,最后将 g 变量设置为 null

接下来,我们调用 System.gc() 方法来尝试触发 GC。

最后,我们尝试重新给 test1 变量赋值,如果 test1 已经被回收,那么就会抛出异常。

结果

运行这段代码后,我们会发现程序会抛出异常,这说明 test1 对象并没有被回收。

原因

那么,为什么 test1 对象没有被回收呢?

这是因为 Java GC 并不是一种实时垃圾回收器,它并不会在对象被设置为 null 后立即回收该对象。

GC 会定期地对内存进行扫描,当它发现某个对象不再被任何引用所指向时,才会将其回收。

在我们的示例中,test1 对象在被设置为 null 后,仍然被 g 变量所指向,因此 GC 不会回收它。

结论

因此,我们可以得出结论:过早地给方法中的引用对象设为 null,并不能让 GC 提前回收该对象。

如果你想让某个对象被 GC 提前回收,你应该确保该对象不再被任何引用所指向。

补充

在某些情况下,给引用对象设为 null 是有用的。

例如,如果你有一个循环,并且在循环中创建了许多临时对象,那么你可以通过在循环结束后将这些对象设置为 null,来帮助 GC 回收这些对象。

但是,如果你想让某个对象被 GC 提前回收,你应该确保该对象不再被任何引用所指向。