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

Java drools规则引擎在一个小规则文件上内存不足,java,drools,rule-engine,Java,Drools,Rule Engine,我编写了一个使用drools规则引擎的java代码。当我试图通过向规则文件(.drl)添加越来越多的规则来测试代码的性能时。当我将100000条规则打包到一个14MB的规则文件中时,程序停止工作 我的规则文件如下所示(模型规则): 下面是应用规则的一段代码: String filename = "rule100000.drl"; Reader reader = new InputStreamReader(ApplyDicomRules.class.getResourceAsStream(file

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

我的规则文件如下所示(模型规则):

下面是应用规则的一段代码:

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();
它在doing addPackageFromDrl行退出,出现以下错误:

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条)放在一个规则文件中吗?

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

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

  • 使用几个DRL文件可以避免OOM问题
  • 此外,尝试6.x版本可能会有所帮助,因为代码生成和编译在5.x和6.x之间发生了变化
  • 然而,当您真正进入执行阶段时,任何包含100000条规则的有意义的规则集都很可能会导致问题

在Drools 6.0版及更高版本中,我认为它需要KIE而不是知识库。以下是我使用的一些东西:

     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堆空间问题的根本原因!!(我也面临同样的问题)

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

规则“发放儿童通行证” 当$ch时:人(年龄<10岁) 不存在(存在ChildPass(childid=$ch.id)) 然后ChildPass$chpass=new ChildPass()$chpass.id=$ch.id;插入($ch);结束


对于有这么多规则的情况,是否最好为每个规则创建一个drl文件?我不明白,当加载相同数量的规则时,如何会有更小的内存占用。每个规则一个文件将陷入另一个极端。100000个文件很不方便编译过程中较小的内存占用是由较少的代码量造成的。至于执行,这可能是另一个问题,但您还没有解决。如果我将其分解为多个drl文件,我只需要调用
rbase.addPackage(pbuilder.getPackage())pbuild时,代码>一次。addPackageFromDrl(drlfile)
多次,对吗?我想你不应该调用PackageBuilder方法-这不在稳定的API中。在Drools 5.x中,您应该使用KnowledgeBuilder,为每个DRL资源调用方法
add(…)
一次,并
getKnowledgePackages()
检索所有包,将其放入KnowledgeBase。更改为KnowledgeBuilder,并获得“无法启动服务”第一行的ClassNotFoundException
KnowledgeBuilder kbuilder=KnowledgeBuilderFactory.newKnowledgeBuilder()导致错误。我正在使用drools core的最终版本6.0.0。根据你们回复的另一篇帖子,我加上了kie的内部依赖性。还是一样的错误。
     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();