【问题标题】:Can objects make each other 'undeletable' by referencing each other?对象可以通过相互引用使对方“不可删除”吗?
【发布时间】:2013-06-04 22:04:37
【问题描述】:

假设有两个类:

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 足够聪明,可以收集孤立对象的孤岛。

标签: java memory-management garbage-collection


【解决方案1】:

没有。垃圾收集器不计算引用以了解对象是否可收集。如果一个对象不再可以通过来自任何根(静态变量或运行线程)的强引用链访问,则该对象是可收集的。

【讨论】:

    【解决方案2】:

    如果仅对 A 和 B 的引用是 A 和 B 本身,则它们有资格进行垃圾回收。

    如果无法通过从垃圾收集根开始的链访问对象,Java 的 GC 会认为这些对象符合垃圾收集条件。即使对象可能相互指向形成一个循环,但如果从根部切断它们仍然是垃圾。

    【讨论】:

      【解决方案3】:

      垃圾收集从活动对象的开始,因此您需要专注于这些集合。如果您有一长串从活动对象引用的对象(当前正在使用的东西指向的东西),那么您可能会造成内存泄漏,但如果您将引用变为 null,这些对象仍将被垃圾收集。

      换句话说,如果您有 A->BB->A 但没有指向两者,它们仍将被收集:因为无法从活动对象的根集访问它们。

      根集来自程序中所有线程的集合:

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

      What are the roots?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-29
        • 1970-01-01
        • 2019-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多