2010-09-16 73 views
0

現在我正在閱讀關於Java垃圾收集的這篇文章:http://www.javaworld.com/javaworld/jw-08-1996/jw-08-gc.htmlJava垃圾收集器澄清

這裏是一個功能的JMS客戶端

public void foo(){ 
    ...//Create Connection factory, connection, and session, topic 

    TopicSubscriber tp = session.createDurableSubcriber(topic,"001"); 
    tp.setMessageListener(this) 
} 

片斷這個問題是不是JMS,但更與對象「TP」發生了什麼FOO()函數調用結束後。函數結束後,無法再引用tp。我假設在createDurableSubscriber()中使用關鍵字「new」,這意味着對象被放置在JVM堆上。然而,由於tp不能再被引用,它受JVM垃圾收集的影響嗎?

回答

2

您需要查看session.createDurableSubcriber()的源代碼,看看它是否不存儲它將返回給你的值。記住你基本上是得到一個指向對象而不是對象本身的指針(稱爲Java引用),並且即使只有一個對象,該指針也可以存儲在許多地方。所有這些指針引用必須在垃圾收集器回收對象之前完成。

+0

所以我想沒有辦法知道肯定,除非你看看源代碼您使用的API ... – Albinoswordfish 2010-09-16 17:37:40

+0

確切地說,或者如果您信任API開發人員。 – 2010-09-16 18:12:15

+0

或信任該API。如果*你使用了某些東西,*你*可以忘記它(只是失去你的參考)。當應用程序的其他部分執行相同操作時,該對象是垃圾。如果你關心後來可以用'tp'做些什麼,那麼保留它。否則,讓API和GC關心如何處理它。他們通常很擅長做這件事。 – cHao 2010-09-16 18:14:57

1

可能。它可能仍然是通過一些指針鏈來引用的,這些指針鏈從某個靜態變量開始。

1

它可以在您的會話中作爲字段引用或在其他任何地方通過,具體取決於JMS實現。 JMS只是一個API,你根本無法假定任何關於實現的東西,並且你不能認爲tp不再被引用。

但是,要回答這個問題,如果你「假設」無論如何它沒有被引用,是的GC會照顧它。

1

僅當沒有運行代碼引用它時纔會收集對象(不包括微弱的引用,但很少有人通常會混淆 - 弱引用不計算用於確定可收集性)。

在您的示例中,如果您認爲create...實際上創建了一個新對象,並且由於某種原因未存儲對該對象的引用,並且將偵聽器附加到該對象上並不需要創建鏈接回到可觀察的,那麼是的 - tp可能有資格進行最終確定和收集。

如果任何這些假設都是錯誤的,但所有投注都關閉。

1

區分對象和變量(保存對象的引用)很重要。當沒有更多引用時,對象就有資格進行垃圾回收。

在您的具體情況下,createDurableSubscriber將保留它返回的引用的副本,從而防止收集對象。 (畢竟,當一個新的消息到達時,它需要調用該對象的方法,這是很難做到沒有參考),