[rules-users] Reclaiming memory usage

Chris Richmond crichmond at referentia.com
Tue Jul 26 06:11:04 EDT 2011


Hello

I am performing a simple test of injecting an event every 1 millisecond 
like so:

       for (int x = 0; x < 100000; x++){
         DataReading dr = new DataReading("Reading " + x, 12.0f);
         myStream.insert(dr);
         ksession.fireAllRules();
         Thread.sleep(1);

       }


The rule that evaluates this is simple.  It basically delays "then" for 
3s to see if a followup reading is inserted and makes sure that no 
ReconfigEvent is active(5s expiration).

So if a reading comes in and a followup reading is not inserted within 3 
seconds and there is is not an existing ReconfigEvent event alive, then 
it should output and insert a ReconfigEvent, essentially disabling any 
DataReading action on those events for the next 5 seconds or so.  This 
all works just fine as expected.

My question is, how come I don't get memory back when all 100,000 of my 
events have been inserted.  Memory goes up slowly over the course of 
insertions, which I can understand, but once that loop is finished, 
memory never reduces, so essentially, the application will eventually 
run out of memory after some time.   I should not have to explicitly 
remove/retract events should I? Shouldn't they be removed from working 
memory as soon as they are no longer viable?  What should I be doing to 
reclaim memory from the session/knowledgebase?

I have included the full Main program here and the Sample.drl file below it.

************FusionMain.java*****************

package com.sample;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.conf.EventProcessingOption;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.conf.ClockTypeOption;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;


public class FusionMain {

   @SuppressWarnings("restriction")
   public static void main(String[] args) {


     try {

       KnowledgeSessionConfiguration config = 
KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
       config.setOption( ClockTypeOption.get("realtime") );


       KnowledgeBase kbase;
       kbase = readKnowledgeBase();
       StatefulKnowledgeSession ksession = 
kbase.newStatefulKnowledgeSession();

       WorkingMemoryEntryPoint myStream = 
ksession.getWorkingMemoryEntryPoint("My Stream");

       for (int x = 0; x < 100000; x++){
         DataReading dr = new DataReading("Reading " + x, 12.0f);
         myStream.insert(dr);
         ksession.fireAllRules();
         Thread.sleep(1);

       }

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

   }

   @SuppressWarnings("restriction")
   private static KnowledgeBase readKnowledgeBase() throws Exception {
     KnowledgeBuilder kbuilder = 
KnowledgeBuilderFactory.newKnowledgeBuilder();
     kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), 
ResourceType.DRL);
     KnowledgeBuilderErrors errors = kbuilder.getErrors();
     if (errors.size() > 0) {
       for (KnowledgeBuilderError error: errors) {
         System.err.println(error);
       }
       throw new IllegalArgumentException("Could not parse knowledge.");
     }

     KnowledgeBaseConfiguration kbConfig = 
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
     kbConfig.setOption( EventProcessingOption.STREAM );
     KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConfig);
     kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());


     return kbase;
   }


}


*********Sample.drl*************************

package com.sample


import java.util.Date;

declare DataReading
     @role( event )
end


declare ReconfigEvent
     @role( event )
     @expires ( 5s )
end



rule "Wait for follup reading or no config"
//lock-on-active
when

     $dr: DataReading(reading > 10.0) from entry-point "My Stream"
     not(DataReading(reading < 10.0, this after[0s,3s] $dr) from 
entry-point "My Stream")
     not(ReconfigEvent() from entry-point "My Stream")

then
     System.err.println("Action: " + new Date(System.currentTimeMillis()));
     System.err.println("Data reading " + $dr.getName() + " > 10");
     ReconfigEvent rce = new ReconfigEvent();
     entryPoints["My Stream"].insert( rce );

end









More information about the rules-users mailing list