<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">It appears there is another condition where Drools holds onto memory indefinitely. (See <a href="https://issues.jboss.org/browse/DROOLS-516">https://issues.jboss.org/browse/DROOLS-516</a>)<div><br></div><div>Use case: We have a set of rules designed to detect a heartbeat, then report when/if the heartbeat stops.</div><div><br></div><div>Problem: In the normal case of a constant heartbeat, memory is retained in the JVM, even though the fact count in working memory is 1.</div><div><br></div><div>The following rules produce this problem. I have attached a test project that demonstrates this problem. 600K events are inserted into the stream, then the test driver waits. After 10 seconds, the “absence detected” rule fires. Requesting a GC via JMC has no effect. If you hit a key while the test driver is waiting, a new event will be added, which will cause the “clear absence alarm” rule to fire. At this point some memory is freed automatically. Requesting another GC removes all memory and the JVM is back in its (nearly) new condition.</div><div><br></div><div>We consider this a memory leak since the events are gone from working memory and will no longer be considered in any rule evaluations, but they are still active somewhere in the JVM.</div><div><br></div><div><span style="font-family: Monaco; font-size: 11px; color: rgb(169, 21, 0);">package</span><span style="font-family: Monaco; font-size: 11px;"> org.drools.example.api.kiemodulemodel</span><span style="font-family: Monaco; font-size: 11px;"> </span></div><div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span style="color: #a91500">import</span> demo.Event </div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">declare<span style="color: #000000"> Event</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> @role( event )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> @timestamp( timestamp )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span style="color: #a91500">declare</span> Heartbeat</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>@role( event )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>@timestamp( event.timestamp )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>event : Event</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span style="color: #a91500">declare</span> AbsenceDetected</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> name : String</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);">/*</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * This rule matches the first event</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> *</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * NOTE: This stream requires the heartbeat event</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * to occur at least once before absence will be detected.</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> */</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 143, 0);"><span style="color: #a91500">rule</span><span style="color: #000000"> </span>"detect first heartbeat"</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">when</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>$event : Event()</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #a91500">not</span> ( Heartbeat() )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">then</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>delete($event);</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #a91500">insert</span>(<span style="color: #a91500">new</span> Heartbeat($event));</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>System.out.println(<span style="color: #008f00">"[DFH] Got event: "</span> + $event.getEventId());</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);">/*</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * This rule matches every event and stores only the most recent</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * as the heartbeat.</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> */</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 143, 0);"><span style="color: #a91500">rule</span><span style="color: #000000"> </span>"keep latest heartbeat"</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">when</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>$heartbeat : Heartbeat()</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>$event : Event()</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">then</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>delete($heartbeat);</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span><span style="color: #a91500">insert</span>(<span style="color: #a91500">new</span> Heartbeat($event));</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>System.out.println(<span style="color: #008f00">"[KLH] Got event: "</span> + $event.getEventId());</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>delete($event);</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);">/*</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * This rule detects when a heartbeat stops for 10s</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> */</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 143, 0);"><span style="color: #a91500">rule</span><span style="color: #000000"> </span>"detect absence"</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);"><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">        </span></span>duration<span style="color: #000000">(10s)</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">when</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>$heartbeat : Heartbeat()</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> <span style="color: #a91500">not</span> ( Event() )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> <span style="color: #a91500">not</span> (AbsenceDetected() )</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">then</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> delete($heartbeat);</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> <span style="color: #a91500">insert</span>(<span style="color: #a91500">new</span> AbsenceDetected(<span style="color: #008f00">"Absence"</span>));</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> System.out.println(<span style="color: #008f00">"[DA] Absence detected"</span>);</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);">/*</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * This rule detects when the heartbeat starts again after </div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> * absence has been detected.</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(146, 144, 0);"> */</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 143, 0);"><span style="color: #a91500">rule</span><span style="color: #000000"> </span>"clear absence alarm"</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">when</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>$heartbeat : Heartbeat()</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"> $absence : AbsenceDetected ()</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">then</div><div style="margin: 0px; font-size: 11px; font-family: Monaco;"><span class="Apple-tab-span" style="white-space:pre">        </span>delete($absence);</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(0, 143, 0);"><span style="color: #000000"><span class="Apple-tab-span" style="white-space:pre">        </span>System.out.println(</span>"[CAA] Heartbeat restored"<span style="color: #000000">);</span></div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(169, 21, 0);">end</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; min-height: 15px;"><br></div></div><div><br></div><div></div></body></html>