My developers and I are having an issue with objects being garbage collected in our application when we don't want them to be. We are using Java with Weblogic 10g3. We are programming a singleton pattern to handle all of our JMS connections.
There are two classes involved:
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
}
The init method of the Servlets calls the JMSFactory singlton method, any new Sessions are placed in the _sessions Hashmap and new MessageConsumer/MessageProducers are created as a JMSObject and placed in the _jmsobjects Hashmap, in the appropriate List.
The problem is that when the system is running the JMSObjects in the list get garbage collected after some time (sometimes in 5 minutes other times after a few hours.) We looked at this for a few days but could not find any reason for the JMSObjects to be garbarge collected. Since the JMSFactory has a reference to them why would the gc destroy them?
In the end we fixed it by changing the classes as follows(without changing method interfaces):
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
}
So far in testing the JMSObjects are not being gc'ed. It has been running for 2 days.
Can someone explain why the indirect reference is causing the JMSObject to get gc'ed? And why the Sessions in the _sessions Hashmap was not getting gc'ed? Does it have anything to do with the fact the Sessions are built in Javax types and the JMSObject is something we wrote?