如果实例变量仍有引用,Java GC 是否会销毁对象?

2022-09-03 06:15:44

我已经在网上阅读了一些Java垃圾回收指南,但我仍然有点不清楚,并希望确保我的代码中没有内存泄漏。

Java GC 是否收集丢失其引用的对象,但其变量仍有引用?

假设我有一些对象:

public class SomeObject {
    public ObjectVar var;

    public SomeObject() {
        var = new ObjectVar();
    }
}

还有我的代码:

SomeObject obj1 = new SomeObject();
SomeObject obj2 = new SomeObject();
obj2.var = obj1.var;
obj1 = null;

所以 obj1 的 var 有引用,但 obj1 不再有任何引用。那么,GC会摧毁obj1,但保持var活着吗?(我假设是这样;只是想确保)。谢谢!


答案 1

这是将要发生的事情(见下面的评论)

// obj1 and obj1.var get created
SomeObject obj1 = new SomeObject();
// obj2 and obj2.var get created
SomeObject obj2 = new SomeObject();
// old obj2.var becomes eligible for GC
obj2.var = obj1.var;
// obj1 becomes eligible for GC
obj1 = null;

最后,仍然存在两个不获取 GCd 的对象 - 以及现在被引用为 .obj2obj1.varobj2.var

注意:在类是 的非静态内部类的特殊情况下,保留 对 的引用也会保留。这是因为在内部,该类有一个隐藏的变量 ,它引用了内部类的外部对象。ObjectVarSomeObjectobj1.varobj1SomeObject.ObjectVarSomeObject


答案 2

是的,当然。

请记住,您在字段中存储的内容实际上是对对象的引用,而不是对象本身。因此,当GC收集时,该对象未被触及(不得触摸),特别是因为它有一个来自 的引用,该引用仍然活着并且很好。varobj1varobj2