Ack'd and queued.

On 07/22/2014 11:46 PM, Kent Anderson wrote:
It appears there is another condition where Drools holds onto memory indefinitely. (See https://issues.jboss.org/browse/DROOLS-516)

Use case: We have a set of rules designed to detect a heartbeat, then report when/if the heartbeat stops.

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.

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.

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.

package org.drools.example.api.kiemodulemodel 

import demo.Event 

declare Event
    @role( event )
    @timestamp( timestamp )
end

declare Heartbeat
@role( event )
@timestamp( event.timestamp )
event   : Event
end

declare AbsenceDetected
    name    : String
end

/*
 * This rule matches the first event
 *
 * NOTE: This stream requires the heartbeat event
 * to occur at least once before absence will be detected.
 */
rule "detect first heartbeat"
when
$event : Event()
not ( Heartbeat() )
then
delete($event);
insert(new Heartbeat($event));
System.out.println("[DFH] Got event: " + $event.getEventId());
end


/*
 * This rule matches every event and stores only the most recent
 * as the heartbeat.
 */
rule "keep latest heartbeat"
when
$heartbeat : Heartbeat()
$event : Event()
then
delete($heartbeat);
insert(new Heartbeat($event));
System.out.println("[KLH] Got event: " + $event.getEventId());
delete($event);
end


/*
 * This rule detects when a heartbeat stops for 10s
 */
rule "detect absence"
duration(10s)
when
$heartbeat : Heartbeat()
    not ( Event() )
    not (AbsenceDetected() )
then
    delete($heartbeat);
    insert(new AbsenceDetected("Absence"));
    System.out.println("[DA] Absence detected");
end

/*
 * This rule detects when the heartbeat starts again after 
 * absence has been detected.
 */
rule "clear absence alarm"
when
$heartbeat : Heartbeat()
    $absence : AbsenceDetected ()
then
delete($absence);
System.out.println("[CAA] Heartbeat restored");
end









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