基于Drools计时器的规则会话始终驻留在内存中并导致内存泄漏

时间:2016-10-30 15:50:02

标签: java memory-leaks drools

我是Drools的新手。我想在解雇规则后延迟5秒(并且只是一次)。所以,我使用timer(int:5s)来做到这一点。但我发现在执行规则后,我的控制台应用程序将永远不会被终止,并且我的任务管理器中仍然存在其javaw.exe进程。唯一的方法是调用ksession.dispose()。但这是不可接受的,因为在我们的集群架构师中很难找到这种关系。

那么,在执行规则后,有没有办法让ksession自动处理?

以下是我的简单测试用例:

  1. 主要课程

    public class App {
        public static void main( String[] args ) {
            System.out.println("Started...");       
    
            KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kbuilder.add(new ClassPathResource("Timer.drl", App.class), ResourceType.DRL); 
            KnowledgeBase kbase = kbuilder.newKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();        
            ksession.fireAllRules();        
    
            System.out.println("Ended");
        }
    }
    
  2. drl file

    package myDrools.TimerTest1
    
    rule "Your First Rule"
    
    timer(int:5s)
    
    when
        eval(true)
    then
        System.out.println("Finished");
    end
    

    输出将是:

    Started...
    Ended
    Finished
    
  3. 但我的控制台应用程序永远不会终止。有什么不对?我在Drools 5.6.0 Final和6.4.0 Final中测试了它。但是,它们都有同样的问题。我认为应该处理ksession,因为timer(int:5s)不是间隔计时器。

2 个答案:

答案 0 :(得分:0)

定时器与托管会话的线程并行运行并使会话保持活动状态。在某种程度上,它们用于运行不确定的会话,即不开始调用fireAllRules。

以下方案应该为您提供干净的关闭:

rule  "Your First Rule"
  timer( int:5s )
when
then
  System.out.println("Finished");
  drools.halt();
end

您的会话就是这样开始的:

kieSession.fireUntilHalt();
System.out.println( "return from fireUntilHalt" );
kieSession.dispose();

修改

如果你需要在任何情况下都要暂停,你可以添加另一个规则,该规则具有否定条件,立即调用停止。

rule "stop if not met"
when
    // negated condition X
then
    drools.halt();
end  

提示:否定条件X not X

答案 1 :(得分:0)

基于laune的好答案,我修改了我的drl文件以确保drools.halt()始终会被命中。 (注意:v6.4.0 Final是可以的。但是v5.6.0 Final会为do子句抛出异常)

dialect "mvel"
rule "Hello World"
timer(int:5s)
when
    m : Message()
    if ( m.status == Message.HELLO)
    do[hello]
then
    System.out.println( "other status" );
    drools.halt();
then[hello]
    System.out.println( "Hello!" );
    drools.halt();