JMS connections are served from a connection pool. This means that calling getConnection() on a Queue connection factory is fast.
Previous to version 8.1, it was possible to reuse a connection with a servlet or EJB component. That is, the servlet could call getConnection() in its init() method and then continually call getSession() for each servlet invocation. If you use JMS within a global transaction, that no longer works: applications can only call getSession() once for each connection. After than, the connection must be closed (which doesn’t actually close the connection; it merely returns it to the pool). This is a general feature of portable Java EE 1.4 applications; the Sun Java System Application Server enforces that restriction where previous (Java EE 1.3-based) application servers did not.
The container for message-driven beans (MDB) is different than the containers for entity and session beans. In the MDB container, sessions and threads are attached to the beans in the MDB pool. This design makes it possible to pool the threads for executing message-driven requests in the container.
Tune the Message-Driven bean’s pool size to optimize the concurrent processing of messages. Set the size of the MDB pool to, based on all the parameters of the server (taking other applications into account). For example, a value greater than 500 is generally too large.
You can configure MDB pool settings in the Admin Console at Configurations > config-name > EJB Container (MDB Settings). You can also set it with asadmin as follows:
asadmin set server.mdb-container.max-pool-size = value
The JMS connection uses two threads and the sessions use one thread each. Since these threads are not taken from a pool and the resultant objects aren’t pooled, you could run out of memory during periods of heavy usage.
One workaround is to move createTopicConnection into the init of the servlet.
Make sure to specifically close the session, or it will stay open, which ties up resources.