Java中的垃圾回收是如何工作的?

11

我想知道Java中的垃圾回收器如何处理以下情况。

对象A引用了对象B,对象B引用了对象C。主程序引用了对象A。因此,您可以通过对象A使用对象B,并通过对象B通过对象A使用对象C。

如果将对象A和对象B之间的链接设置为null,则对象B和对象C会发生什么?

如果现在对象A和对象B之间的链接被设置为null,垃圾回收器是否应该对对象B和对象C进行回收呢?我的意思是,对象B和对象C之间仍然存在连接。


我在另一篇帖子中提出了另一个问题:https://dev59.com/A3E95IYBdhLWcg3wJKp_ - JordyOnrust
9个回答

9

对象B和对象C现在应该被垃圾回收器收集吗?

是的。因为没有通过根A访问对象B和C的方式,它们成为了垃圾回收的候选对象。


6

如果B和C无法从任何GC根(GC根通常是所有线程和堆栈上的所有引用)到达,则它们可以进行垃圾回收。


3
@Maurice:据我所知,不能直接访问静态变量。可以通过它们所属的Class来访问静态变量,而这个Class可以通过加载它们的ClassLoader来访问,而这个ClassLoader又可以通过加载其他类型的对象来访问。因此,如果ClassLoader被垃圾回收了,甚至可能会丢失静态变量的值。 - Joachim Sauer
@Joachim:静态变量不是类的一部分,而是对象吗? - JordyOnrust
@Joachim:请看主题开始,我添加了一个额外的问题。 - JordyOnrust

4

你不能指望垃圾收集器在特定时间工作,因为它的行为是不可预测的,你只能说B和C对象仅适合进行垃圾回收。


4

通常情况下,这篇文章是必读的,想要了解垃圾回收的人需要阅读。它写得很好,并带有解释性图示。


打开链接时,我需要输入用户名和密码。 - JordyOnrust
啊,FTP又出问题了。我已经编辑了我的帖子,并提供了另一个链接,应该会更好用。还有一个PDF版本。 - Thomas Pornin
@Bright010957:搞定了!https://ritdml.rit.edu/dspace/bitstream/1850/5112/1/PWilsonProceedings1992.pdf - Philip Potter

2
事实上,在Java中的垃圾回收是一件非常复杂的事情,比如在Ruby解释器中要复杂得多。但无论如何,理论基础是相同的。GC会识别程序代码不再引用的对象图(也就是说,它们在活动代码中没有更多的引用)。当谈到对象图时,我确切地谈论B->C对象图。一旦它不可达,它就可以被垃圾回收,但你不能确定何时会发生这种情况,因为GC试图尽可能地优化其工作以避免减慢应用程序的运行速度。

2
由于您无法再访问B和C,它们可以进行垃圾回收。由于垃圾收集器的不可预测性,我们只知道它们很可能在未来的某个时间被回收。

1

我认为逻辑是不同的。如果对象不能从线程访问,则可以进行回收。


1

如果没有对象的引用,那么垃圾回收程序就可以进行了。


0

B没有引用它,因此它将首先进行垃圾回收,然后它会理解C没有引用它,因此C也将被垃圾回收。这只是为了说明,JVM足够聪明,可以一次性地处理它们。


2
无法确定B将首先进行垃圾回收,即您不应该在B和C中具有依赖于该顺序的终结器代码。GC不计算引用,而是检查可达性。如果B和C都无法到达,则它们是同样不可达的。 - Erich Kitzmueller

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