i have got some questions concerning invoking and pooling of Stateless Session Beans (SLSB).
we use JBoss 4.2.2, default configuration, EJB3 SLSBs are pooled by ThreadlocalPool (deploy/ejb3-interceptors-aop.xml). we noticed from JMX Console that the SLSB pools blow up in the long run, meaning that a lot of SLSB objects are kept in heap space. we investigated this behaviour and it seems that thread creation may be the root case of the problem.
our client uses Remote Method Invocation (RMI) through the DefaultEjb3Connector (JBoss Remoting Connector, deploy\ejb3.deployer\META-INF\jboss-service.xml). the Remoting Connector installs an AcceptorThread. whenever a client does invoke a Remote Business Interface method a SocketServerInvoker routes the client invocation from this AcceptorThread to a WorkerThread (ServerThread) that actually handles the request.
in case multiple clients invoke methods concurrent, multiple WorkerThreads are created from AcceptorThread, thus we got t running WorkerThreads on the server (where t corresponds to the maximum of concurrent client invocations at a single moment). it seems that these WorkerThreads stay alive after invocation response and get used by next client invocations.
now a client invocation triggers some business logic to be performed on the server. this process involves b SLSBs (starting from client with remote invocation and using several local invocations between EJBs!). for each SLSB there is a pool (ThreadlocalPool as mentioned before). the ThreadlocalPool creates new instances of our EJBs for every WorkerThread on the server (see StatelessInstanceInterceptor.invoke) and always keeps one of these instances (see ThreadlocalPool.release). as the result there are t * b bean instances that will never be destroyed until server shutdown (note: it is possible to stop SLSB pool, destroying all the bean instances (InfinitePool.destroy), but we dont want to manually start/ stop these pools during runtime!).
we think this is a strange behaviour! just imagine 100 clients invoke some business functionality at the same time. that creates 100 WorkerThreads. assumming that the business logic involves 5 different EJBs there will be 100 * 5 = 500 objects (bean instances) in the heap space. and these objects will never be released/ destroyed!?
maybe i just did not find it... so let me simply ask for it:
- is there a mechanism that removes (killes or finishes) WorkerThreads after responding to the client?
or are these threads supposed to stay alive forever?
in addition we deploy a MessageDrivenBean (MDB) on the server and register it to a Queue. the MDB is a single instance MDB (configured by ActivationConfigProperty maxSession=1). the clients may send messages to this Queue to inform the server about some status and the MDB will process these messages one by one.
when a message is received the onMessage method of our MDB is invoked in so called WorkManager thread (PooledInvoker invokes JmsServerSession.run which invokes onMessage on the MDB). the onMessage again involves several EJBs (local invocations!) and therefor instances of these EJBs are create from ThreadlocalPool. after a message is processed the WorkManager thread finishes, thus dies. but after the thread died the bean instances created by the ThreadlocalPool are kept in InfinitePool.active. that means if JBoss is running some days without restart and the MDB receives more and more messages (each processed by a newly created thread), the pool blows up, because ThreadlocalPool does not destroy the bean instances ever. is this the way it is supposed to be?? or
- is there a mechanism that removes bean instances from ThreadlocalPool (respectively from InfinitePool.active) after the corresponding thread died??
i read some documentation in WIKI and the forums. there was mentioned another Pool implementation: StrictMaxPool. StrictMaxPool does not create bean instances per thread, but creates instances on demand, restricted by a maximum pool size. for MDBs the StrictMaxPool is configured as default in ejb3-interceptors-aop.xml, but for SessionBeans it is ThreadlocalPool.
- why are there different default pool configurations for Session- and MessageDrivenBeans?
- what are the advantages and disadvantages of ThreadlocalPool and StrictMaxPool (performance??)?
are there general guide lines that explain when to use ThreadlocalPool or StrictMaxPool?
- could StrictMaxPool solve the problems that ThreadlocalPool causes in the situations described above?
StrictMaxPool should not keep bean instances, but release them after response -independent of which thread created and used the bean, shouldnt it?
i am confused by the different mechanism that handle Remote Method Invocations and incovations through Java Messaging... so i would be glad if someone could explain these differences to me, especially in case of the SLSB pools, threading of client invocations.
thanks in advance