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 <je...@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@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>

_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users

Reply via email to