对象之间引用可以使彼此“不可删除”吗?

5

假设有两个类:

public class A {
    B reference = new B(this) //B isn't garbage collected because A references it
}

public class B {
    A reference // A isn't garbage collected because B references it
    public B(A ref) {
      reference = ref;
    }
}

然后第三类创建了一个新的A对象。当要摆脱它时,将该指针设置为null。由于它们互相引用,A和B是否会导致一些奇怪的持久循环?它们彼此“保持活动状态”,因此都无法被收集。或者JVM太聪明了,意识到程序的其余部分不知道它们?
感觉这可能会导致某种类型的内存泄漏。
如果可能的话,如何解决?双向引用在代码中非常常见。有许多情况下,对象1知道对象2,对象2知道对象1。如何确保它们被删除。
注意:我在网页浏览器中编写了所有这些内容,因此请原谅任何错误。

Java中的GC足够智能,可以收集孤立对象的岛屿。 - Ravi K Thapliyal
3个回答

10

不会。垃圾回收器不会计算引用以确定对象是否可以被收集。只有当某个对象从任何根(静态变量或运行线程)的强引用链路中不可到达时,它才能被收集。


6
如果只有对A和B的引用是A和B本身,那么它们就可以进行垃圾回收。
Java的GC认为如果对象不能通过从垃圾回收根开始的链路到达,则它们有资格进行垃圾回收。即使对象彼此指向形成一个循环,如果它们与根断开连接,它们仍然是垃圾。

2
垃圾回收从活动对象的根开始,因此您需要集中处理这些集合。如果您有一长串被活动对象引用的对象链(指当前正在使用的东西所指向的东西),则可能会创建内存泄漏,但是如果将引用设置为 null,则这些对象仍将被垃圾收集。
换句话说,如果您有 A->BB->A 但没有任何指向两者的指针,它们仍然会被收集:因为它们无法从活动对象的根集合中到达。
根集合来自程序中所有线程的集合:

http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx

"and"
"

根是什么?

"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接