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