We have found a workaround that eliminates the leftover event
(gone from Working Memory, but not from the JVM memory):
The rule “forget it ever happened” (seen below) causes the
problem. Re-writing it to remove the check for RAISE in the LHS
eliminated the memory leak. Of course, our application requires
the check for RAISE, so it can be accomplished by manually
querying working memory from the RHS. It’s ugly, but it
resolved the issue.
query existsRaise($id)
$raise
: MyEvent( eventState == EventState.RAISE, eventId == $id )
end
rule "process clear"
no-loop
when
$clear
: MyEvent(eventState == EventState.CLEAR, $clearId : eventId)
then
QueryResults
results = kcontext.getKieRuntime().getQueryResults( "existsRaise", $clearId );
if (results.size() == 0) {
System.out.println(
"Forwarding CLEAR(" +
$clearId + ")" );
} else {
System.out.println("Forgetting RAISE/CLEAR(" +
$clearId + ")");
for (QueryResultsRow
row : results){
MyEvent
raise = (MyEvent) row.get ("$raise");
delete(raise);
}
}
delete($clear);
end
Correction: The
original post did not include another rule that exists in
the stream. The memory leak does not appear unless both
rules are active in the stream.
declare
MyEvent
@role(event)
@timestamp(timestamp)
end
/* If a RAISE is
buffered for N seconds, send it out */
rule "forward
raise"
no-loop
duration (3s)
when
$raise :
MyEvent(eventState == EventState.RAISE, $raiseId :
eventId)
then
System.out.println("Forwarding RAISE(" +
$raiseId + ")");
delete($raise);
end
/* When CLEAR, and
buffered, clear them both out */
rule "forget it
ever happened"
no-loop
when
$clear :
MyEvent(eventState == EventState.CLEAR, $clearId :
eventId)
$raise :
MyEvent(eventState == EventState.RAISE, eventId ==
$clearId)
then
System.out.println("Forgetting RAISE/CLEAR("
+ $clearId + ")");
delete($clear);
delete($raise);
end
The
following rule produces a memory leak in Drools
6.1.0-SNAPSHOT:
(Stream mode)
declare MyEvent
@role(event)
@timestamp(timestamp)
end
/*
If a RAISE is buffered for N seconds, send it
out */
rule "forward raise"
no-loop
duration (3s)
when
$raise : MyEvent(eventState ==
EventState.RAISE, $raiseId : eventId)
then
System.out.println("Forwarding RAISE(" + $raiseId
+ ")");
delete($raise);
end
I see the rule fire as expected, printing out
the message 3 seconds after the event is added
into the session. While the event is waiting, I
see a FactCount of 1 in the session. After the
rule fires, the fact count goes to 0. However,
using JVisualVm, querying the heap dump shows 1
instance of MyEvent, referenced by an
EventFactHandle and several other Drools objects.
Is this a bug, or is there a better way to
write this rule so Drools’ internals let go of the
object after it is no longer a fact?
<PastedGraphic-1.png>
<PastedGraphic-2.png>
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users