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

时间:2013-05-16 23:31:04

标签: java garbage-collection

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

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

所以我想说我有SomeObject:

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存活吗? (我假设是这样;只是想确定)。谢谢!

4 个答案:

答案 0 :(得分:16)

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

// 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的对象 - obj2和前obj1.var现在被称为obj2.var

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

答案 1 :(得分:3)

当然可以。

请记住,您在var字段中存储的内容实际上是对象的引用,而不是对象本身。因此,当GC收集obj1时,var对象不受影响(不得触及),尤其是因为它有来自obj2的引用,它仍然存在好吧..

答案 2 :(得分:0)

是 - 行为如您所述。垃圾收集的一般规则是,只有当您无法通过任何硬引用访问它们时,对象才有资格。因此,您可以通过这种方式访问​​的任何对象都不会被垃圾回收(软/弱引用除外。)

答案 3 :(得分:0)

简单地说,如果一个对象仍然可以通过引用路径到达,那么它可以保证在收集后继续存在。如果没有这样的路径,则无法再访问该对象,并且可以安全地收集该对象。

在前两行之后,内存看起来像这样:

o1  --> SomeObj#1 --> ObjectVar#1
o2  --> SomeObj#2 --> ObjectVar#2

如果此时发生垃圾收集,则可以到达所有4个对象,不会收集任何对象。

在第3行之后,它看起来像这样:

o1  --> SomeObj#1 --> ObjectVar#1
                      ^
o2  --> SomeObj#2 -----    ObjectVar#2

现在,只能到达3个物体;垃圾收集器可以删除ObjectVar#2。

在第4行之后,它看起来像这样:

o1      SomeObj#1 --> ObjectVar#1
                      ^
o2  --> SomeObj#2 -----   ObjectVar#2

仍然只能访问两个对象;垃圾收集器可能会删除SomeObj#1和ObjectVar#2,但必须保留SomeObj#2和ObjectVar#1。