我和我的开发人员在我们不希望对象被垃圾回收时遇到了问题。我们将 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 是我们编写的东西有关吗?