2015-06-03 2 views
0

Я написал код Java, который использует механизм управления слюнами. Когда я пытался проверить производительность кода, добавив все больше правил в файл правила (.drl). Программа перестала работать, когда я упаковал 100000 правил в файле правил 14 МБ.двигатель drools rule исчерпал память в файле небольшого правила

Мой файл правило выглядит следующим образом (правила макетных):

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

Ну, я бы не назвал файл, содержащий 100000 правил «маленький», что, согласно моему любимому словарю, означает «немного в количестве или немного в количестве», а 100000 - это не просто «несколько». Если у этого эксперимента есть какой-то серьезный фон, вы должны пересмотреть свой подход - скорее всего, вы ошибаетесь.

Это не говорит о том, что у Rro Engine Drools не хватает памяти: это компилятор Java, который не может обрабатывать это количество исходного кода в одном файле Java.

  • Использование нескольких файлов DRL должно обойти проблему OOM.
  • Кроме того, попытка версии 6.x может помочь, поскольку генерация и компиляция кода изменилась между 5.x и 6.x.
  • Однако вполне вероятно, что любой набор правил, содержащий 100000, будет создавать проблемы, когда вы действительно достигнете стадии выполнения.
+0

Для ситуации с таким количеством правил лучше ли создавать один файл drl для каждого правила? Я не понимаю, как это будет иметь меньший объем памяти при загрузке того же количества правил. – Nasreddin

+0

Один файл за правило попадает в другую крайность. 100000 файлов вряд ли удобно. - меньший объем памяти ** во время компиляции ** получается из меньшего количества кода. Что касается исполнения, это может быть другой проблемой, но вы еще не зарегистрированы. – laune

+0

Если я разбиваю его на несколько drl-файлов, мне нужно только вызвать 'rbase.addPackage (pbuilder.getPackage()); 'один раз, когда я запускаю' pbuild. addPackageFromDrl (drlfile) 'несколько раз, правильно? – Nasreddin

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(); 

Но я не думаю, что это Teh основная причина проблемы Java Heap пространства !! (Я тоже сталкиваюсь с той же проблемой)

0

Привет, проблема в том, что увольнение правил вставляет новые факты и в конечном итоге заканчивается память. Два способа обработки: 1. добавьте no-loop true 2. Чтобы написать условия, при которых правила запускаются только при выполнении условий.

rule "issue child pass" when $ch:Person (age < 10) not(exists ChildPass (childid == $ch.id)) then ChildPass $chpass = new ChildPass(); $chpass.id= $ch.id; insert($ch); end

Смежные вопросы