Java垃圾收集器澄清

现在我正在读这篇关于Java垃圾收集的文章: http : //www.javaworld.com/javaworld/jw-08-1996/jw-08-gc.html ?

这是JMS客户端中的一个函数片段

public void foo(){ ...//Create Connection factory, connection, and session, topic TopicSubscriber tp = session.createDurableSubcriber(topic,"001"); tp.setMessageListener(this) } 

这个问题不是关于JMS,而是关于foo()函数调用结束后对象“tp”会发生什么。 函数结束后,再也无法引用tp了。 我假设在createDurableSubscriber()中它使用关键字“new”,这意味着该对象被放置在JVM堆上。 但是,由于tp不再被引用,它是否受JVM垃圾回收的影响?

您需要查看session.createDurableSubcriber()的源代码,看看它是否存储了它将在某处返回给您的值。

记住,你基本上得到一个指针(在Java中称为引用)到对象,而不是对象本身,即使你只有一个对象,指针也可以存储在很多地方。 在垃圾回收器回收对象之前,必须完成所有这些指针引用。

有可能。 它可能仍然通过一些指针链引用,这些指针从一个静态变量开始。

它可以在您的会话中作为字段引用,也可以在其他任何位置传递,具体取决于JMS实现。 JMS只是一个API,您根本无法假设有关实现的任何内容,并且您不能认为tp不再被引用。

但要回答这个问题,如果你“假设”无论如何都没有引用它,是的,GC会照顾它。

只有在没有正在运行的代码引用它的情况下才会收集一个对象(不包括弱引用,无论如何通常都很少有人参与 – 弱引用不能用于确定可收集性)。

在您的示例中,如果您假设create...实际上创建了一个新对象,并且由于某种原因不存储对它的引用,并且将侦听器附加到所述对象不需要创建返回到observable的链接,然后是 – tp可能有资格进行最终确定和收集。

但是,如果这些假设中的任何一个都是错误的,那么所有的赌注都会被取消。

区分对象和变量(包含对象的引用)很重要。 当没有对象的引用时,对象就有资格进行垃圾回收。

在您的特定情况下, createDurableSubscriber将保留它返回的引用的副本,从而阻止收集该对象。 (毕竟,它需要在新消息到达时调用该对象上的方法,这在没有引用的情况下很难做到),