【问题标题】:Two Object references point to each other两个对象引用相互指向
【发布时间】:2013-07-09 08:25:37
【问题描述】:

在目标 C 中,两个不同的引用有可能相互指向。

但这在 Java 中可能吗? 我的意思是,两个对象引用可以相互指向吗?如果可能的话,它们什么时候会被垃圾回收?

而且,在嵌套类的情况下,两个对象(内部类和外部类)相互链接 - 这些对象是如何被垃圾回收的?

【问题讨论】:

  • 一个对象引用只能指向一个对象。两个相互指向的对象引用是什么意思?
  • 哦!我是java新手!在嵌套类的情况下,两个对象(内部类和外部类)相互链接。如果我在这里有任何意义,这两个如何收集垃圾

标签: java


【解决方案1】:

我假设您在谈论循环引用。如果无法通过从 GC 根开始的链访问对象,Java 的 GC 会将其视为“垃圾”。即使对象之间可能相互指向形成一个循环,但如果从根中切断,它们仍然有资格进行 GC。

Java 中有四种 GC 根:

  1. 局部变量通过线程堆栈保持活动状态。这不是真实的对象虚拟参考,因此不可见。出于所有意图和目的,局部变量都是 GC 根。

  2. 活动 Java 线程始终被视为活动对象,因此是 GC 根。这对于线程局部变量尤其重要。

  3. 静态变量由它们的类引用。这一事实使它们成为事实上的 GC 根源。类本身可以被垃圾收集,这将删除所有引用的静态变量。当我们通常使用应用程序服务器、OSGi 容器或类加载器时,这一点特别重要。

  4. JNI 引用是本机代码在 JNI 调用中创建的 Java 对象。这样创建的对象会被特殊处理,因为 JVM 不知道它是否被本机代码引用。这样的对象代表了一种非常特殊的 GC 根。

您也可以阅读here 了解更多信息。

【讨论】:

  • 这是否意味着如果垃圾收集器收集了该类并且程序将来再次使用它,则静态初始化程序可以在单个类中运行多次?
【解决方案2】:

是的,您可以这样做。像这样:

class Pointy {
    public Pointy other;
}

Pointy one = new Pointy();
Pointy two = new Pointy();
one.other = two;
two.other = one;

当两个对象都没有被任何其他对象指向时,或者当前运行的代码“无法访问”的其他对象时,它们就会被垃圾回收。 Java 垃圾收集器是"tracing" garbage collectors,这意味着他们可以发现这类问题。

相反,reference-counted 系统(例如没有“现代”垃圾收集的 Objective C ——我不知道默认值是什么)通常无法检测到此类问题,因此对象可能会被泄露。

【讨论】:

    【解决方案3】:

    当然,您可以让对象相互引用。您可以简单地将两个对象中的 this 指针相互传递,这是完全有效的。

    但是,这并不意味着仍然可以从 GC 根目录访问这些对象。把它想象成一棵(图)树。如果你从主干上切掉一个完整的分支,那么整个分支都会丢失,无论涉及多少对象或维护彼此的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 2015-04-06
      • 2021-09-19
      • 1970-01-01
      • 2014-06-18
      相关资源
      最近更新 更多