<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><font face="Courier New">We’re running DROOLS 6.1.0-SNAPSHOT and are seeing unbounded memory growth for certain rules. I’ve put together an example that&nbsp;reproduces the problem using a rule based on (but not identical to) one that we are seeing memory leaks. I’m not sure if the&nbsp;leaks are caused by poorly written rules or by something else.<br><br>The attached example can be built and run using maven, i.e. “mvn install exec:exec” It’s running DROOLS in stream mode using a&nbsp;real-time clock and using EQUALITY equals behavior. The input to the rules are events that are identified by their eventId (a&nbsp;long value) and a state enumeration having 3 possible values: ACTIVE, INACTIVE and ACCEPTED. The rules are supposed to work&nbsp;like this:<br><br>1. If an event is received with a state of ACTIVE and no event having that eventId has been captured, then capture the event&nbsp;data in a new fact (CapturedEvent) and delete the event.<br>2. If an event is received with a state of INACTIVE and an event having the same eventId has previously been captured, then&nbsp;delete the CapturedEvent fact.<br>3. If, after 10 seconds the CapturedEvent fact is still there then set its state to ACCEPTED.<br>4. All other events &nbsp;facts are deleted.<br><br>Not a real useful example, but it does demonstrate either a memory leak or a poorly written set of rules.<br><br>After creating the KieSession in streams mode, the demo starts inserting event facts every 5ms. There are 1000 different&nbsp;eventIds - each iteration of events being inserted sends one event with each eventId. Initially the events state is set to&nbsp;ACTIVE. Periodically the events state is set to INACTIVE for one iteration, then back to ACTIVE. The intent is that 1000&nbsp;different events will, 10 seconds after they’re first inserted, transition from ACTIVE to ACCEPTED. Then shortly after the&nbsp;INACTIVE events are sent and all 1000 CapturedEvent facts are deleted. The cycle then repeats until 500,000 events have been&nbsp;inserted into the session. Because all events are deleted by one of the rules, at the end of the run there should be 1000 facts&nbsp;of type CapturedEvent in the session since the final iteration of events all have a state of ACTIVE.<br><br>For example, the set of events look something like this:<br><br>Time<span class="Apple-tab-span" style="white-space:pre">        </span>ID<span class="Apple-tab-span" style="white-space:pre">        </span>State</font><div><font face="Courier New">0.000s<span class="Apple-tab-span" style="white-space:pre">        </span>0<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">0.005s<span class="Apple-tab-span" style="white-space:pre">        </span>1<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">0.010s<span class="Apple-tab-span" style="white-space:pre">        </span>2<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">…</font></div><div><font face="Courier New">4.995s<span class="Apple-tab-span" style="white-space:pre">        </span>999<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">5.000s<span class="Apple-tab-span" style="white-space:pre">        </span>0<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">5.005s<span class="Apple-tab-span" style="white-space:pre">        </span>1<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">…</font></div><div><font face="Courier New">9.995s<span class="Apple-tab-span" style="white-space:pre">        </span>999<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">10.000s<span class="Apple-tab-span" style="white-space:pre">        </span>0<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">10.005s<span class="Apple-tab-span" style="white-space:pre">        </span>1<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">…</font></div><div><font face="Courier New">14.995s<span class="Apple-tab-span" style="white-space:pre">        </span>999<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New">15.000s<span class="Apple-tab-span" style="white-space:pre">        </span>0<span class="Apple-tab-span" style="white-space:pre">        </span>INACTIVE</font></div><div><font face="Courier New">15.005s<span class="Apple-tab-span" style="white-space:pre">        </span>1<span class="Apple-tab-span" style="white-space:pre">        </span>INACTIVE</font></div><div><font face="Courier New">15.010s<span class="Apple-tab-span" style="white-space:pre">        </span>2<span class="Apple-tab-span" style="white-space:pre">        </span>INACTIVE</font></div><div><font face="Courier New">…</font></div><div><font face="Courier New">19.995s<span class="Apple-tab-span" style="white-space:pre">        </span>999<span class="Apple-tab-span" style="white-space:pre">        </span>INACTIVE</font></div><div><font face="Courier New">20.000s<span class="Apple-tab-span" style="white-space:pre">        </span>0<span class="Apple-tab-span" style="white-space:pre">        </span>ACTIVE</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">and so on until a total of 500,000 events are inserted. Each iteration of 1000 events takes 5 seconds. So basically the first three iterations the events are ACTIVE then the fourth iteration the events are INACTIVE, then three more iterations of ACTIVE, etc.</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">What actually happens is that the rules actually work but only once for each ID. So, for example, the first insert of event ID 0 with state of ACTIVE matches the&nbsp;“capture active” rule as expected. The second insert of event ID 0 with state of ACTIVE matches the&nbsp;“delete events” rule. 10 seconds after the first event with ID 0 arrives, the&nbsp;“ensure active” rule matches. The third ACTIVE event also matches the&nbsp;“delete event” rule. When the fourth event with ID 0 and state INACTIVE is inserted that matches the&nbsp;“restart timer” rule which deletes the CapturedEvent fact.&nbsp;When the next event with ID 0 and state ACTIVE is inserted, I expected the&nbsp;“capture active” rule to fire because the CapturedEvent fact was deleted. But instead the&nbsp;“delete events” rule matches, and from this point on all events trigger the&nbsp;“delete events” rule.</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">After garbage collection, analysis of the heap dump shows there are 248,000 instances of org.drools.core.reteoo.RightTuple objects and the same number of org.drools.core.common.PhreakPropagationContext objects. Also, there are 124,000 instances of org.drools.core.c</font><span style="font-family: 'Courier New';">ommon.EventFactHandle objects, even though the reported fact count is 0.</span></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">The demo project is attached.</font></div><div><font face="Courier New"><br></font></div><div></div></body></html>