]
Fabio Strozzi updated JBRULES-3559:
-----------------------------------
Attachment: bpmLeak.zip
Test application that reproduces the memory leakage
Memory leakage when no transaction manager is used
--------------------------------------------------
Key: JBRULES-3559
URL:
https://issues.jboss.org/browse/JBRULES-3559
Project: Drools
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: drools-core
Affects Versions: 5.3.1.Final, 5.4.0.Final
Environment: JBPM 5.2.Final, Drools 5.3.1.Final, Weblogic 10.3.5, JRockit
R28.2.2-7-148152-1.6.0_29-20111221-2104-linux-x86_64, Spring 3.0.5
Reporter: Fabio Strozzi
Assignee: Mark Proctor
Labels: drools-persistence-jpa, jbpm5, leak, memory, memory_leak,
memoryleak
Attachments: bpmLeak.zip
Hi,
a memory leak appears in Drools if a StatefulKnowledgeSession is created without a
transaction manager being speciifed (despite the fact that the dispose method is called
for each session, be it created or loaded).
To be more clear, this is the code that creates the session:
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
return JPAKnowledgeService.newStatefulKnowledgeSession(readKnowledgeBase(), null,
env);
When analyzing the memory dumps of a Spring-based webapplication that uses JBPM, under
stress conditions, the Eclipse Memory Analyzer blames
org.drools.persistence.SingleSessionCommandService class as the main cause of the leakage.
This class is taking up to the 46% of the whole heap by accumulating instances of
java.lang.Object[] arrays. These arrays are actually elements of a synchronized map called
sysnchronizations (see SingleSessionCommandService.java, line 73).
For my understanding of the source code of Drools, the sysnchronizations map is filled
every time the registerRollbackSync method of SingleSessionCommandService is called; on
the other hand, its elements are removed only if a JtaTransactionSynchronizationAdapter is
successfully registered against the transaction (via
javax.transaction.Transaction.registerSynchronization method).
If I understand it correctly, this happens only if a javax.transaction.TransactionManager
object is specified in the environment properties or one is found by
JtaTransactionManager.findTransactionManager.
When no transaction manager is present (or none is found by findTransactionManager),
method SynchronizationImpl.afterCompletion (the only one eligible to remove elements from
SingleSessionCommandService.synchronizations) is never called and memory increases with
each new session.
Please note that if no transaction synchronization manager is passed as an environement
property, then org.drools.persistence.jta.JtaTransactionManager never finds it, even if
the JNDI lookup successfully retrieves it; method findTransactionSynchronizationRegistry
never sets the tsr attribute, hence if it was null at the time the method is called, so it
is when it returns.
I also tried to set the transaction manager but I still get a constant memory
consumption. The Eclipse Memory Analyzer claims that, in this case, class
org.drools.reteoo.ReteooStatefulSession is suspected for the leakage.
As a final note, there's a minor issue in class JtaTransactionSynchronizationAdapter:
at line 31, the afterCompletion method is called on object this rather than on object ts
(TransactionSynchronization). This could cause a loop if status is STATUS_ACTIVE.
I'm working on a test case to reproduce the memory issues. I will provide one as soon
as possible along with a heap dump.
Fabio
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: