首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >drools规则引擎在一个小规则文件上内存不足

drools规则引擎在一个小规则文件上内存不足
EN

Stack Overflow用户
提问于 2015-06-04 04:57:53
回答 3查看 3.3K关注 0票数 0

我写了一段使用drools规则引擎的java代码。当我试图通过向规则文件(.drl)添加越来越多的规则来测试代码的性能时。当我将100000条规则打包到一个14MB的规则文件中时,程序停止工作。

我的规则文件看起来像这样(模拟规则):

代码语言:javascript
复制
package drools.rules

import drools.DicomImage

rule "PHI rule0"

    when
        $di : DicomImage(boolName == true)
    then
        System.out.println("rule 0 is applied");
end

rule "PHI rule1"

    when
        $di : DicomImage(boolName == true)
    then
        System.out.println("rule 1 is applied");
end

rule "PHI rule2"

    when
        $di : DicomImage(boolName == true)
    then
        System.out.println("rule 2 is applied");
end

以下是应用规则的代码片段:

代码语言:javascript
复制
String filename = "rule100000.drl";
Reader reader = new InputStreamReader(ApplyDicomRules.class.getResourceAsStream(filename));
PackageBuilder pBuilder = new PackageBuilder();
pbuilder.addPackageFromDrl(reader);

Rulebase rbase = RuleBaseFactory.newRuleBase();
rbase.addPackage(pbuilder.getPackage());

runRules();

它在执行addPackageFromDrl时退出,出现以下错误:

代码语言:javascript
复制
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.lang.Throwable.printStackTrace(Unknown Source)
 at org.eclipse.jdt.internal.compiler.util.Util.getExceptionSummary(Util.java:627)
 at org.eclipse.jdt.internal.compiler.Compiler.handleInternalException(Compiler.java:587)
 at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:522)
 at org.drools.compiler.commons.jci.compilers.EclipseJavaCompiler.compile(EclipseJavaCompiler.java:405)
 at org.drools.compiler.commons.jci.compilers.AbstractJavaCompiler.compile(AbstractJavaCompiler.java:49)
 at org.drools.compiler.rule.builder.dialect.java.JavaDialect.compileAll(JavaDialect.java:405)
 at org.drools.compiler.compiler.DialectCompiletimeRegistry.compileAll(DialectCompiletimeRegistry.java:46)
 at org.drools.compiler.compiler.PackageRegistry.compileAll(PackageRegistry.java:107)
 at org.drools.compiler.compiler.PackageBuilder.compileAll(PackageBuilder.java:1317)
 at org.drools.compiler.compiler.PackageBuilder.compileAllRules(PackageBuilder.java:968)
 at org.drools.compiler.compiler.PackageBuilder.addPackage(PackageBuilder.java:956)
 at org.drools.compiler.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:452)
 at org.drools.compiler.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:428)
 at drools.ApplyDicomRules.initializeDrools(ApplyDicomRules.java:65)
 at drools.ApplyDicomRules.main(ApplyDicomRules.java:26)

即使我用-Xms1024m运行它也不能工作。我认为它无论如何都不需要那么多内存。并且我只将规则应用于单个事实(对象)。

是什么花了这么多的内存?我不应该在一个规则文件中放入那么多规则(100000条)吗?

EN

回答 3

Stack Overflow用户

发布于 2015-06-04 13:36:10

嗯,我不会把一个包含100000条规则的文件称为“小”,根据我最喜欢的字典,它的意思是“数量很少或数量很少”,而100000不仅仅是“几条”。如果这个实验有任何严肃的背景,你应该重新考虑你的方法-最有可能的是,你走错了路。

也就是说,并不是Drools规则引擎耗尽了内存: Java编译器无法在单个Java文件中处理如此多的源代码。

使用多个DRL文件的

  • 应该可以绕过面向对象模型问题。
  • 另外,尝试6.x版本可能会有所帮助,因为代码生成和编译在5.x和6.x之间发生了变化。
  • 但是,任何由100000组成的有意义的规则集很可能会在您真正到达执行阶段时导致问题。
票数 0
EN

Stack Overflow用户

发布于 2015-11-30 13:25:39

在Drools 6.0及更高版本中,我相信它需要的是KIE而不是KnowledgeBase。下面是我用到的一些东西:

代码语言:javascript
复制
     KieServices kieServices = KieServices.Factory.get();
     KieFileSystem kfs = kieServices.newKieFileSystem();
     FileInputStream fis = new FileInputStream(path to your .drl file);
     kfs.write(path to your drl file,kieServices.getResources().newInputStreamResource( fis ));
     KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
     Results results = kieBuilder.getResults();
    if( results.hasMessages( Message.Level.ERROR ) ){
        System.out.println( results.getMessages() );
        throw new IllegalStateException( "### errors ###" );
    }

    KieContainer kieContainer = kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );
    KieBaseConfiguration config = kieServices.newKieBaseConfiguration();

但我不认为这是Java堆空间问题的根本原因!(我也面临同样的问题)

票数 0
EN

Stack Overflow用户

发布于 2016-03-03 09:36:45

问题可能是触发规则,插入新的事实,并最终耗尽内存。有两种处理方法: 1.添加无循环true 2.编写条件,使规则仅在满足条件时触发。

规则“发出孩子通行证”when $ch:Person (年龄< 10) not(exists ChildPass (childid == $ch.id)) then ChildPass $chpass = new ChildPass();$chpass.id= $ch.id;insert($ch);end

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30630577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档