我写了一个使用drools规则引擎的java代码。当我试图通过向规则文件(.drl)添加越来越多的规则来测试代码的性能时。当我在14MB规则文件中打包100000个规则时,程序停止工作。
我的规则文件如下所示(模拟规则):
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
以下是适用规则的代码:
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的行中退出并出现以下错误:
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)放在一个规则文件中吗?
答案 0 :(得分:0)
好吧,我不打电话给一个包含100000条规则的文件" small",根据我最喜欢的词典,这意味着数量很少或数量很少",和100000不仅仅是一些"少数"。如果这个实验有任何严重的背景,你应该重新考虑你的方法 - 很可能,你走错了路。
那就是说,Drools规则引擎并不是内存不足的:它是Java编译器,无法在单个Java文件中处理这么多的源代码。
答案 1 :(得分:0)
在Drools 6.0及更高版本中,我认为它需要KIE而不是KnowledgeBase。这是我使用的东西:
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堆空间问题的根本原因! (我也面临同样的问题)
答案 2 :(得分:0)
嗨问题可能是规则的触发插入新事实并最终耗尽内存。两种处理方式: 1.添加无循环真 2.编写条件,以便仅在满足条件时才触发规则。
规则&#34;发出儿童通行证&#34; 当$ ch:人(年龄<10) not(存在ChildPass(childid == $ ch.id)) 然后ChildPass $ chpass = new ChildPass(); $ chpass.id = $ ch.id;插入($ CH);端