现在我正在阅读有关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垃圾回收的影响?
答案 0 :(得分:2)
您需要查看session.createDurableSubcriber()
的源代码,看看它是否存储了它将在某处返回给您的值。
请记住,您基本上是在对象中获取指针(在Java中称为引用),而不是对象本身,即使您只有一个对象,该指针也可以存储在多个位置。在垃圾收集器回收对象之前,必须完成所有这些指针引用。
答案 1 :(得分:1)
可能。它可能仍然通过一些指针链引用,这些指针从某处的静态变量开始。
答案 2 :(得分:1)
它可以在您的会话中作为字段引用,也可以在其他任何位置传递,具体取决于JMS实现。
JMS只是一个API,您根本无法假设任何有关实现的内容,并且您不能认为tp
不再被引用。
但要回答这个问题,如果你“假设”无论如何都没有被引用,那么GC就会照顾它。
答案 3 :(得分:1)
只有当没有正在运行的代码具有对它的引用时才会收集一个对象(不包括弱引用,无论如何通常很少有人参与 - 弱引用不计入确定可收集性。)
在您的示例中,如果您假设create...
实际上创建了一个新对象,并且由于某种原因没有存储对它的引用,并且将侦听器附加到所述对象不需要创建链接回到可观察的,然后是 - tp
可能有资格进行最终确定和收集。
如果这些假设中的任何一个都是错误的,那么所有的赌注都会被取消。
答案 4 :(得分:1)
区分对象和变量(保存对象的引用)很重要。当没有对象的引用时,对象就有资格进行垃圾收集。
在您的特定情况下,createDurableSubscriber
将保留其返回的引用的副本,从而阻止收集该对象。 (毕竟,它需要在新消息到达时调用该对象上的方法,这在没有引用的情况下很难做到),