[jboss-svn-commits] JBL Code SVN: r32176 - in labs/jbossrules/trunk: drools-compiler/src/test/resources/org/drools/integrationtests and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Mar 22 16:02:43 EDT 2010


Author: tirelli
Date: 2010-03-22 16:02:42 -0400 (Mon, 22 Mar 2010)
New Revision: 32176

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MemoryLeak.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/OutOfMemoryTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ModifyPreviousTuples.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java
Log:
JBRULES-2340: fixing memory leak on logical inserts

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/OutOfMemoryTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/OutOfMemoryTest.java	2010-03-22 19:55:49 UTC (rev 32175)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/OutOfMemoryTest.java	2010-03-22 20:02:42 UTC (rev 32176)
@@ -17,20 +17,30 @@
  */
 
 import java.io.InputStreamReader;
+import java.util.Collection;
 
 import junit.framework.TestCase;
 
 import org.drools.Cheese;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.Person;
 import org.drools.RuleBase;
 import org.drools.RuleBaseConfiguration;
 import org.drools.RuleBaseFactory;
 import org.drools.SessionConfiguration;
 import org.drools.StatefulSession;
 import org.drools.WorkingMemory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
 import org.drools.compiler.PackageBuilder;
+import org.drools.io.ResourceFactory;
 import org.drools.rule.Package;
+import org.drools.runtime.ObjectFilter;
+import org.drools.runtime.StatefulKnowledgeSession;
 
-
 /** Run all the tests with the ReteOO engine implementation */
 public class OutOfMemoryTest extends TestCase {
 
@@ -46,7 +56,7 @@
                                             config );
     }
 
-    public void FIXME_testStatefulSessionsCreation() throws Exception {
+    public void testStatefulSessionsCreation() throws Exception {
 
         final PackageBuilder builder = new PackageBuilder();
         builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_OutOfMemoryError.drl" ) ) );
@@ -54,25 +64,26 @@
 
         RuleBase ruleBase = getRuleBase();
         ruleBase.addPackage( pkg );
-        ruleBase    = SerializationHelper.serializeObject(ruleBase);
+        ruleBase = SerializationHelper.serializeObject( ruleBase );
 
         int i = 0;
-        
+
         SessionConfiguration conf = new SessionConfiguration();
         conf.setKeepReference( true ); // this is just for documentation purposes, since the default value is "true"
         try {
-            for( i = 0; i < 300000; i++ ) {
-                final StatefulSession session = ruleBase.newStatefulSession( conf, null );
+            for ( i = 0; i < 300000; i++ ) {
+                final StatefulSession session = ruleBase.newStatefulSession( conf,
+                                                                             null );
                 session.dispose();
-            } 
+            }
         } catch ( Throwable e ) {
-            System.out.println("Error at: "+i);
+            System.out.println( "Error at: " + i );
             e.printStackTrace();
-            fail("Should not raise any error or exception.");
+            fail( "Should not raise any error or exception." );
         }
 
     }
-    
+
     public void testAgendaLoop() throws Exception {
         final PackageBuilder builder = new PackageBuilder();
         builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_OutOfMemory.drl" ) ) );
@@ -80,7 +91,7 @@
 
         RuleBase ruleBase = getRuleBase();
         ruleBase.addPackage( pkg );
-        ruleBase    = SerializationHelper.serializeObject(ruleBase);
+        ruleBase = SerializationHelper.serializeObject( ruleBase );
         final WorkingMemory workingMemory = ruleBase.newStatefulSession();
 
         workingMemory.insert( new Cheese( "stilton",
@@ -91,4 +102,46 @@
         // just for profiling
         //Thread.currentThread().wait();
     }
+
+    public void testMemoryLeak() {
+        final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( ResourceFactory.newClassPathResource( "test_memoryLeak.drl", OutOfMemoryTest.class ),
+                      ResourceType.DRL );
+        assertFalse( kbuilder.getErrors().toString(), kbuilder.hasErrors() );
+        
+        final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+        
+        final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+        
+        final int pcount = 2;
+        Person[] persons = new Person[pcount];
+        FactHandle[] pHandles = new FactHandle[pcount];
+        for( int i = 0; i < persons.length; i++ ) {
+            persons[i] = new Person( "person"+i );
+            pHandles[i] = ksession.insert( persons[i] );
+        }
+        
+        ksession.fireAllRules() ;
+        Collection< ? > logicals = getLogicallyInserted( ksession );
+        assertEquals( pcount, logicals.size() );
+        
+        for(int i = 0; i < pcount; i++ ) {
+            persons[i].setName( "personA"+i );
+            ksession.update( pHandles[i], persons[i] );
+        }
+        
+        ksession.fireAllRules() ;
+        logicals = getLogicallyInserted( ksession );
+        assertEquals( pcount, logicals.size() );
+    }
+
+    private Collection< ? > getLogicallyInserted(final StatefulKnowledgeSession ksession) {
+        Collection<?> logicals = ksession.getObjects( new ObjectFilter() {
+            public boolean accept(Object object) {
+                return object.getClass().getSimpleName().equals( "PersonName" );
+            }
+        });
+        return logicals;
+    }
 }
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MemoryLeak.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MemoryLeak.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MemoryLeak.drl	2010-03-22 20:02:42 UTC (rev 32176)
@@ -0,0 +1,14 @@
+package org.drools
+
+declare PersonName
+   name : String @key
+end
+
+rule "Rule 1"
+    when
+        $p: Person()
+    then
+        PersonName pn = new PersonName();
+        pn.setName( $p.getName() );
+        insertLogical( pn ); 
+end

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ModifyPreviousTuples.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ModifyPreviousTuples.java	2010-03-22 19:55:49 UTC (rev 32175)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ModifyPreviousTuples.java	2010-03-22 20:02:42 UTC (rev 32176)
@@ -49,7 +49,10 @@
                 return current;
             } else {
                 this.leftTuples = new IdentityHashMap<LeftTupleSink, LeftTuple>();
-                for ( ; leftTuple != null; leftTuple = (LeftTuple) leftTuple.getLeftParentNext() ) {
+                for ( LeftTuple next = null; leftTuple != null; leftTuple = next  ) {
+                    next = leftTuple.getLeftParentNext();
+                    leftTuple.setLeftParentPrevious( null );
+                    leftTuple.setLeftParentNext( null );
                     this.leftTuples.put( leftTuple.getLeftTupleSink(),
                                          leftTuple );
                 }
@@ -72,7 +75,10 @@
                 return current;
             } else {
                 this.rightTuples = new IdentityHashMap<RightTupleSink, RightTuple>();
-                for ( ; rightTuple != null; rightTuple = (RightTuple) rightTuple.getHandleNext() ) {
+                for ( RightTuple next = null ; rightTuple != null; rightTuple = next ) {
+                    next = rightTuple.getHandleNext();
+                    rightTuple.setHandlePrevious( null );
+                    rightTuple.setHandleNext( null );
                     this.rightTuples.put( rightTuple.getRightTupleSink(),
                                           rightTuple );
                 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2010-03-22 19:55:49 UTC (rev 32175)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2010-03-22 20:02:42 UTC (rev 32176)
@@ -31,8 +31,6 @@
 import org.drools.common.InternalWorkingMemory;
 import org.drools.common.PropagationContextImpl;
 import org.drools.common.ScheduledAgendaItem;
-import org.drools.core.util.Iterator;
-import org.drools.core.util.LeftTupleList;
 import org.drools.event.rule.ActivationCancelledCause;
 import org.drools.reteoo.RuleRemovalContext.CleanupAdapter;
 import org.drools.reteoo.builder.BuildContext;
@@ -319,6 +317,9 @@
             agenda.scheduleItem( (ScheduledAgendaItem) item,
                                  workingMemory );
             item.setActivated( true );
+            workingMemory.removeLogicalDependencies( item,
+                                                     context,
+                                                     this.rule );
 
             ((EventSupport) workingMemory).getAgendaEventSupport().fireActivationCreated( item,
                                                                                           workingMemory );
@@ -342,7 +343,9 @@
             item.setActivated( added );
 
             if ( added ) {
-                item.setActivated( true );
+                workingMemory.removeLogicalDependencies( item,
+                                                         context,
+                                                         this.rule );
                 ((EventSupport) workingMemory).getAgendaEventSupport().fireActivationCreated( item,
                                                                                               workingMemory );
             }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java	2010-03-22 19:55:49 UTC (rev 32175)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java	2010-03-22 20:02:42 UTC (rev 32176)
@@ -200,5 +200,10 @@
             }
         }
     }
+    
+    @Override
+    public String toString() {
+        return this.expression.toString();
+    }
 
-};
\ No newline at end of file
+}
\ No newline at end of file



More information about the jboss-svn-commits mailing list