If we can get a unit test for this, we are just about to put out 5.6 (which has 
a lot of important fixes in it already), we'll try and have it fixed for then.

Mark
On 17 Feb 2013, at 08:55, Wolfgang Laun <wolfgang.l...@gmail.com> wrote:

> With Drools 5.4.0.Final and 5.5.0.Final, automatic event retraction in
> combination with a sliding window is broken, i.e., it suffers from a
> memory leak. Full code for a demo has been posted by tai-atari; so I
> just add some diagnostics that clearly indicate what goes wrong.
> 
> In the snapshot taken with jmap -histo:live after running the program
> for several seconds and the insertion of 15800 AnEvent facts you can
> see:
>   * several classes with 2000 instances each - AnEvents and the ones
> required for bookkeeping the future expiry
>   *  EventFactHandle, WindowTupleList, ObjectHashMap$ObjectEntry all
> growing without restraint, indicating a memory leak.
> 
> 
> num     #instances         #bytes  class name
> ----------------------------------------------
>   1:          8747        8696096  [S
>   2:         26985        4110776  <constMethodKlass>
>   3:         26985        2161888  <methodKlass>
>   4:         47816        2046304  <symbolKlass>
>   5:          2414        1482672  <constantPoolKlass>
>   6:          6142        1434280  [I
>   7:         13800        1324800  org.drools.common.EventFactHandle
>   8:          2414        1056424  <instanceKlassKlass>
>   9:          1891         854664  <constantPoolCacheKlass>
>  10:          8348         644704  [C
>  11:         13800         441600  org.drools.reteoo.WindowTupleList
>  12:          2571         426976  [B
>  13:         15800         379200
> org.drools.core.util.ObjectHashMap$ObjectEntry
>  14:          2672         256512  java.lang.Class
>  15:           545         246776  <methodDataKlass>
>  16:          7852         188448  java.lang.String
>  17:          4084         185496  [[I
>  18:          2000         176000  org.drools.common.PropagationContextImpl
>  19:             8         164288  [Lorg.drools.core.util.Entry;
>  20:          2000         160000  org.drools.common.AgendaItem
>  21:          2005         128320  org.drools.reteoo.WindowTuple
>  22:          2000         128000  org.drools.reteoo.RuleTerminalNodeLeftTuple
>  23:          2001          96048  java.util.concurrent.FutureTask$Sync
>  24:          2001          80040
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
>  25:          1165          79152  [J
>  26:           229          75112  <objArrayKlassKlass>
>  27:          2001          64032
> org.drools.time.impl.JDKTimerService$JDKJobHandle
>  28:          2001          64032  
> org.drools.time.impl.DefaultTimerJobInstance
>  29:           423          54728  [Ljava.lang.Object;
>  30:          2150          51600  java.util.LinkedList$Entry
>  31:          2052          49248  java.util.LinkedList
>  32:          2002          48048
> org.drools.core.util.ObjectHashSet$ObjectEntry
>  33:          2001          48024  java.util.Date
>  34:          2000          48000
> org.drools.reteoo.ObjectTypeNode$ExpireJobContext
>  35:          1958          46992  java.util.HashMap$Entry
>  36:          2261          36176  java.lang.Integer
>  37:          2006          32096  java.util.concurrent.atomic.AtomicBoolean
>  38:          2001          32016  org.drools.time.impl.PointInTimeTrigger
>  39:          2000          32000
> org.drools.reteoo.ReteooWorkingMemory$WorkingMemoryReteExpireAction
>  40:          2000          32000  memcons.AnEvent
> 
> 
> 
> 
> On 17/02/2013, tai-atari <p00tem...@gmail.com> wrote:
>> Hi laune,
>> 
>> Really appreciate you trying to reproduce the issue. Since you are not
>> experiencing the same behavior I'm obviously missing something. I've
>> attached a very simple example below which reproduces the scenario for the
>> Drools versions I have tried so far: 5.2, 5.4 and 5.5.
>> 
>> Basically this example runs an infinite loop which inserts 200 events about
>> every second, and keeps a sliding window of 10 seconds. Every loop will
>> print the current wm event count, which will increase to 2000 and stay put.
>> This is where I expected the expired events to be available for garbage
>> collection (since only 2000 are concurrently active in wm). But VisualVM
>> shows that org.drools.common.EventFactHandle uses an increasing amount of
>> memory over time.
>> 
>> Start.java:
>> ==================================
>> package org.drools.example;
>> 
>> import java.util.Random;
>> 
>> 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.runtime.StatefulKnowledgeSession;
>> import org.drools.runtime.rule.WorkingMemoryEntryPoint;
>> 
>> public class Start {
>> 
>>    public static final void main(String[] args) {
>>        try {
>>              
>>              System.out.println("Init");
>>            KnowledgeBase kbase = readKnowledgeBase();
>>            StatefulKnowledgeSession ksession =
>> kbase.newStatefulKnowledgeSession();
>>            WorkingMemoryEntryPoint eventStream =
>> ksession.getWorkingMemoryEntryPoint("TheEventStream");
>>                      Random randGen = new Random();
>>                      
>>            while( true ) {
>> 
>>                  // Insert 200
>>                  int x = 0;
>>                  while( x < 200 ) {
>>                      AnEvent anEvent = new AnEvent();
>>                      anEvent.setSource(randGen.nextInt());
>>                      eventStream.insert(anEvent);
>>                      ksession.fireAllRules();
>>                      x++;
>>                   }
>>      
>>                System.out.println("current event count in wm" + ": " +
>> eventStream.getFactCount());
>>                  Thread.sleep(1000);
>>            }
>> 
>>            //ksession.dispose();
>> 
>>        } catch (Throwable t) {
>>            t.printStackTrace();
>>        }
>>    }
>>      
>>      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.");
>>          }
>>      
>>          final KnowledgeBaseConfiguration kbConfig =
>> KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
>>          kbConfig.setOption(EventProcessingOption.STREAM);
>>          KnowledgeBase kbase = 
>> KnowledgeBaseFactory.newKnowledgeBase(kbConfig);
>> 
>>          kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
>>          return kbase;
>>      }
>>      
>> }
>> ==================================
>> 
>> AnEvent.java:
>> ==================================
>> package org.drools.example;
>> 
>> public class AnEvent {
>> 
>>      private Integer source;
>>      
>>          public AnEvent () {
>>          }
>> 
>>              public Integer getSource() {
>>                      return source;
>>              }
>> 
>>              public void setSource(Integer source) {
>>                      this.source = source;
>>              }
>> 
>> }
>> ==================================
>> 
>> Sample.drl
>> ==================================
>> package org.drools.example
>> import org.drools.example.AnEvent;
>> 
>> declare AnEvent
>>      @role( event )
>> end
>> 
>> rule "Event print"
>> when
>>      AnEvent ( $src: source ) over window:time(10s) from entry-point
>> TheEventStream
>> then
>>      System.out.println("---------> Received AnEvent from " + $src);
>> end
>> ==================================
>> 
>> Also tried using an immutable pojo as you suggested cusmaimatteo, with
>> 
>> AnEvent.java:
>> ==================================
>> package org.drools.example;
>> 
>> public class AnEvent {
>> 
>>      private final Integer source;
>>      
>>          public AnEvent (Integer i) {
>>              this.source = i;
>>          }
>> 
>>              public Integer getSource() {
>>                      return source;
>>              }
>> }
>> ==================================
>> 
>> and using instead using
>> 
>> eventStream.insert(new AnEvent(randGen.nextInt()));
>> 
>> but with the same memory issues noted.
>> 
>> 
>> 
>> 
>> 
>> --
>> View this message in context:
>> http://drools.46999.n3.nabble.com/Garbage-collection-and-sliding-windows-Drools-5-5-0-Final-tp4022183p4022350.html
>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>> _______________________________________________
>> rules-users mailing list
>> rules-us...@lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>> 
> _______________________________________________
> rules-users mailing list
> rules-us...@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users


_______________________________________________
rules-dev mailing list
rules-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-dev

Reply via email to