Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-765

Memory leak with incremental rules

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 6.3.0.CR2
    • 6.2.0.Final
    • core engine
    • None
    • Hide

      import java.io.StringReader;
      import java.util.ArrayList;
      import java.util.List;

      import org.kie.api.KieServices;
      import org.kie.api.builder.KieBuilder;
      import org.kie.api.builder.KieFileSystem;
      import org.kie.api.builder.KieModule;
      import org.kie.api.builder.ReleaseId;
      import org.kie.api.builder.Results;
      import org.kie.api.io.ResourceType;
      import org.kie.api.runtime.KieContainer;
      import org.kie.api.runtime.KieSession;
      import org.kie.internal.builder.IncrementalResults;
      import org.kie.internal.builder.InternalKieBuilder;

      public class TestDroolsRules {

      public static void main(String[] args) {

      ReleaseId releaseId1 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.1" );
      ReleaseId releaseId2 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.2" );

      String drl1 = "package org.drools.compiler\n" +
      "global java.util.List list\n" +
      "rule R0 when then list.add( \"000\" ); end \n" +
      "" +
      "rule R1 when\n" +
      " $s : String() " +
      "then\n" +
      " list.add( \"a\" + $s );" +
      "end\n";

      String drl2 = true
      ?
      "package org.drools.compiler\n" +
      "global java.util.List list\n" +
      "declare StringWrapper\n" +
      " s : String\n" +
      "end\n" +
      "rule RInit when\n" +
      " $s : String() \n" +
      "then\n" +
      " insert( new StringWrapper( $s ) );" +
      "end\n" +
      "rule R2 when\n" +
      " $s : StringWrapper() \n" +
      "then\n" +
      " list.add( \"b\" + $s.getS() );" +
      "end\n"
      :
      "package org.drools.compiler\n" +
      "global java.util.List list\n" +
      "rule R2 when\n" +
      " $s : String() \n" +
      "then\n" +
      " list.add( \"b\" + $s );" +
      "end\n";

      KieServices ks = KieServices.Factory.get();
      KieFileSystem kfs = ks.newKieFileSystem();

      KieBuilder kieBuilder = ks.newKieBuilder( kfs );

      kfs.generateAndWritePomXML( releaseId1 );
      kfs.write( ks.getResources()
      .newReaderResource( new StringReader( drl1 ) )
      .setResourceType( ResourceType.DRL )
      .setSourcePath( "drl1.txt" ) );

      kieBuilder.buildAll();
      System.out.println("results is " + kieBuilder.getResults().getMessages());
      // assertEquals( 0, kieBuilder.getResults().getMessages().size() );
      KieModule kieModule = kieBuilder.getKieModule();
      System.out.println("kiemodule version is " + kieModule.getReleaseId());

      // assertEquals( releaseId1, kieModule.getReleaseId() );

      KieContainer kc = ks.newKieContainer( releaseId1 );

      try

      { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }

      KieSession ksession = kc.newKieSession();
      List<String> list = new ArrayList<String>();
      ksession.setGlobal( "list", list );
      ksession.insert( "Foo" );
      ksession.fireAllRules();

      System.out.println("List size is " + list.size());
      System.out.println("list is " + list);


      try { Thread.sleep(30000); }

      catch (InterruptedException e)

      { // TODO Auto-generated catch block e.printStackTrace(); }

      // assertEquals( 2, list.size() );
      // assertTrue( list.containsAll( asList( "000", "aFoo" ) ) );
      list.clear();

      kfs.generateAndWritePomXML( releaseId2 );
      kfs.write( ks.getResources()
      .newReaderResource( new StringReader( drl2 ) )
      .setResourceType( ResourceType.DRL )
      .setSourcePath( "drl2.txt" ) );

      IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild();

      System.out.println("added messages is " + results.getAddedMessages());

      // assertEquals( 0, results.getAddedMessages().size() );

      kieModule = kieBuilder.getKieModule();
      // assertEquals( releaseId2, kieModule.getReleaseId() );

      System.out.println("kiemodule version is " + kieModule.getReleaseId());

      Results updateResults = kc.updateToVersion( releaseId2 );
      // assertEquals( 0, updateResults.getMessages().size() );

      System.out.println("updated results is " + updateResults.getMessages());

      try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }

      ksession.insert( "Bar" );
      ksession.fireAllRules();

      // assertEquals( 3, list.size() );
      //assertTrue( list.containsAll( asList( "bBar", "bFoo", "aBar" ) ) );

      System.out.println("List size is " + list.size());
      System.out.println("list is " + list);

      }

      }

      use jmap to find instances of RuleImpl after each sleep statement.

      Show
      import java.io.StringReader; import java.util.ArrayList; import java.util.List; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.KieModule; import org.kie.api.builder.ReleaseId; import org.kie.api.builder.Results; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.internal.builder.IncrementalResults; import org.kie.internal.builder.InternalKieBuilder; public class TestDroolsRules { public static void main(String[] args) { ReleaseId releaseId1 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.1" ); ReleaseId releaseId2 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.2" ); String drl1 = "package org.drools.compiler\n" + "global java.util.List list\n" + "rule R0 when then list.add( \"000\" ); end \n" + "" + "rule R1 when\n" + " $s : String() " + "then\n" + " list.add( \"a\" + $s );" + "end\n"; String drl2 = true ? "package org.drools.compiler\n" + "global java.util.List list\n" + "declare StringWrapper\n" + " s : String\n" + "end\n" + "rule RInit when\n" + " $s : String() \n" + "then\n" + " insert( new StringWrapper( $s ) );" + "end\n" + "rule R2 when\n" + " $s : StringWrapper() \n" + "then\n" + " list.add( \"b\" + $s.getS() );" + "end\n" : "package org.drools.compiler\n" + "global java.util.List list\n" + "rule R2 when\n" + " $s : String() \n" + "then\n" + " list.add( \"b\" + $s );" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( releaseId1 ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.txt" ) ); kieBuilder.buildAll(); System.out.println("results is " + kieBuilder.getResults().getMessages()); // assertEquals( 0, kieBuilder.getResults().getMessages().size() ); KieModule kieModule = kieBuilder.getKieModule(); System.out.println("kiemodule version is " + kieModule.getReleaseId()); // assertEquals( releaseId1, kieModule.getReleaseId() ); KieContainer kc = ks.newKieContainer( releaseId1 ); try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "Foo" ); ksession.fireAllRules(); System.out.println("List size is " + list.size()); System.out.println("list is " + list); try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // assertEquals( 2, list.size() ); // assertTrue( list.containsAll( asList( "000", "aFoo" ) ) ); list.clear(); kfs.generateAndWritePomXML( releaseId2 ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl2.txt" ) ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild(); System.out.println("added messages is " + results.getAddedMessages()); // assertEquals( 0, results.getAddedMessages().size() ); kieModule = kieBuilder.getKieModule(); // assertEquals( releaseId2, kieModule.getReleaseId() ); System.out.println("kiemodule version is " + kieModule.getReleaseId()); Results updateResults = kc.updateToVersion( releaseId2 ); // assertEquals( 0, updateResults.getMessages().size() ); System.out.println("updated results is " + updateResults.getMessages()); try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } ksession.insert( "Bar" ); ksession.fireAllRules(); // assertEquals( 3, list.size() ); //assertTrue( list.containsAll( asList( "bBar", "bFoo", "aBar" ) ) ); System.out.println("List size is " + list.size()); System.out.println("list is " + list); } } use jmap to find instances of RuleImpl after each sleep statement.

      When doing incremental builds you will see that memory usage is higher then when you do a fresh start. I have found that the number of instances of RuleImpl in heap when doing incremental builds are double what you would expect. For instance, if I start with 10 rules then there are 10 instances of RuleImpl. If I add 5 more rules instead of 15 instsances of RuleImpl I see 20. This means that incremental rules are using more memory then they should.

              mfusco@redhat.com Mario Fusco
              seanmmorris_jira Sean Morris (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: