【发布时间】:2010-11-10 12:43:03
【问题描述】:
我和我的开发人员在我们不希望对象被垃圾回收时遇到了问题。我们将 Java 与 Weblogic 10g3 一起使用。我们正在编写一个单例模式来处理我们所有的 JMS 连接。
涉及两个类:
public class JMSObject {
...
private MessageProducer _producer;
private MessageConsumer _consumer;
...
// standard get/set procs... etc.
}
public class JMSFactory {
...
// Hashmap sessions with key == ConnectionFactory Name
Hashmap<String, List<Session>> _sessions;
// Hashmap of JMSObjects with key == ConnectionFactory Name + JMS Queue Name
Hashmap<String, List<JMSObject>> _jmsobjects;
...
// standard get/set & necessary sington functions
}
Servlet 的 init 方法调用 JMSFactory singlton 方法,任何新的 Session 都被放置在 _sessions Hashmap 中,新的 MessageConsumer/MessageProducers 被创建为 JMSObject 并放置在 _jmsobjects Hashmap 中的相应列表中。
问题是当系统运行时,列表中的 JMSObjects 会在一段时间后收集垃圾(有时是 5 分钟,有时是几个小时后)。我们看了几天,但找不到任何原因用于垃圾收集的 JMSObjects。既然 JMSFactory 引用了它们,为什么 gc 会销毁它们?
最后我们通过如下改变类来修复它(不改变方法接口):
public class JMSObject {
...
private List<MessageProducer> _producers;
private List<MessageConsumer> _consumers;
...
// standard get/set procs... etc.
}
public class JMSFactory {
...
// Hashmap sessions with key == ConnectionFactory Name
Hashmap<String, List<Session>> _sessions;
// Hashmap of JMSObjects with key == ConnectionFactory Name + JMS Queue Name
private Hashmap<String JMSObject> _jmsobjects;
...
// standard get/set & necessary sington functions
}
到目前为止,在测试 JMSObjects 时还没有被 gc'ed。它已经运行了 2 天。
有人可以解释为什么间接引用会导致 JMSObject 被 gc'ed 吗?为什么 _sessions Hashmap 中的 Sessions 没有被 gc'ed?这与 Session 是用 Javax 类型构建的,而 JMSObject 是我们编写的这一事实有什么关系吗?
【问题讨论】:
-
当
JMSObjects 被垃圾收集时,我认为列表的大小保持不变,但是当您尝试阅读它时会得到nulls? -
@Jack Leow,是的 NullPointerException... :-(
标签: java jakarta-ee garbage-collection jms weblogic