返回
过早的给方法中引用对象设为null可被GC提前回收吗?实验揭秘真相!
后端
2023-12-10 14:54:57
过早地给方法中的引用对象设为 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 提前回收,你应该确保该对象不再被任何引用所指向。