[rules-users] Improving Drools Memory Performance

Wolfgang Laun wolfgang.laun at gmail.com
Fri Jul 9 07:39:24 EDT 2010


Your sample rule is indeed causing maximum memory usage for the Rete.

With your "ideas" you are definitly on the right track. Not knowing what
is hidden in functions.*() or handelr.*() one can't rewrite this rule.
Just some observations:

(a)  eval ( handler.veto( detail )) - This condition can be checked
three lines up, in detail: DetailWire().
(b) container : Frame( ) - This is useless, since you get eContainer
as an attribute from VisibleThing (At most, it ensures that this isn't
null.)
(c) I'm inclined to believe that all the functions.*() can be written
as conditions on attributes, doing away with all the evals.

HTH
-W



On 9 July 2010 10:20, Jevon Wright <jevon at jevon.org> wrote:
> Hi everyone,
>
> I am working on what appears to be a fairly complex rule base based on
> EMF. The rules aren't operating over a huge number of facts (less than
> 10,000 EObjects) and there aren't too many rules (less than 300), but
> I am having a problem with running out of Java heap space (set at ~400
> MB).
>
> Through investigation, I came to the conclusion that this is due to
> the design of the rules, rather than the number of facts. The engine
> uses less memory inserting many facts that use simple rules, compared
> with inserting few facts that use many rules.
>
> Can anybody suggest some tips for reducing heap memory usage in
> Drools? I don't have a time constraint, only a heap/memory constraint.
> A sample rule in my project looks like this:
>
>  rule "Create QueryParameter for target container of DetailWire"
>    when
>      container : Frame( )
>      schema : DomainSchema ( )
>      domainSource : DomainSource ( )
>      instance : DomainIterator( )
>      selectEdge : SelectEdge ( eval (
> functions.connectsSelect(selectEdge, instance, domainSource )) )
>      schemaEdge : SchemaEdge ( eval (
> functions.connectsSchema(schemaEdge, domainSource, schema )) )
>      source : VisibleThing ( eContainer == container )
>      target : Frame ( )
>      instanceSet : SetWire ( eval(functions.connectsSet(instanceSet,
> instance, source )) )
>      detail : DetailWire ( )
>      eval ( functions.connectsDetail(detail, source, target ))
>      pk : DomainAttribute ( eContainer == schema, primaryKey == true )
>      not ( queryPk : QueryParameter ( eContainer == target, name == pk.name ) )
>      eval ( handler.veto( detail ))
>
>    then
>      QueryParameter qp = handler.generatedQueryParameter(detail, target);
>      handler.setName(qp, pk.getName());
>      queue.add(qp, drools); // wraps insert(...)
>
>  end
>
> I try to order the select statements in an order that will reduce the
> size of the cross-product (in theory), but I also try and keep the
> rules fairly human readable. I try to avoid comparison operators like
> < and >. Analysing a heap dump shows that most of the memory is being
> used in StatefulSession.nodeMemories > PrimitiveLongMap.
>
> I am using a StatefulSession; if I understand correctly, I can't use a
> StatelessSession with sequential mode since I am inserting facts as
> part of the rules. If I also understand correctly, I'd like the Rete
> graph to be tall, rather than wide.
>
> Some ideas I have thought of include the following:
> 1. Creating a separate intermediary meta-model to split up the sizes
> of the rules. e.g. instead of (if A and B and C then insert D), using
> (if A and B then insert E; if E and C then insert D).
> 2. Moving eval() statements directly into the Type(...) selectors.
> 3. Removing eval() statements. Would this allow for better indexing by
> the Rete algorithm?
> 4. Reducing the height, or the width, of the class hierarchy of the
> facts. e.g. Removing interfaces or abstract classes to reduce the
> possible matches. Would this make a difference?
> 5. Conversely, increasing the height, or the width, of the class
> hierarchy. e.g. Adding interfaces or abstract classes to reduce field
> accessors.
> 6. Instead of using EObject.eContainer, creating an explicit
> containment property in all of my EObjects.
> 7. Creating a DSL that is human-readable, but allows for the
> automation of some of these approaches.
> 8. Moving all rules into one rule file, or splitting up rules into
> smaller files.
>
> Is there kind of profiler for Drools that will let me see the size (or
> the memory usage) of particular rules, or of the memory used after
> inference? Ideally I'd use this to profile any changes.
>
> Thanks for any thoughts or tips! :-)
>
> Jevon
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>




More information about the rules-users mailing list