Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
I wanted to circle back before this thread gets too far off the original topic and folks searching in the future don't get confused. I am still confused between the 'or' and '||' as explained here and in the documentation. I will attempt to review this in more detail. In the meantime, I have simplified my rules per the above comments and am able to run them with about 10M facts in under 3 hours. The system required more than 40GB of RAM. I am chunking the data and running multiple threads. I will look to reduce the overhead where possible as I am certain their are further improvements that can be made. Once I complete out my refactoring and reviews, I'll circle back again. Needless to say, things have moved in a very positive direction. I am not sure what memory expectations I should have so I'll take a complete run in this timeframe without errors as a win. Thank you, Wolgang and Mark. You guys have been fantastic! On Mon, Feb 25, 2013 at 3:13 AM, Mark Proctor mproc...@codehaus.org wrote: On 25 Feb 2013, at 06:46, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Mark Proctor mproc...@codehaus.org wrote: when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) same here Are you sure you want 'or' and not ||. Mark, how would you suggest to avoid 'or' and use '||' (and I don't mean the deprecated alternative to 'or')? You are beginning to confuse (even) me! Many people do not want CE 'or' they want infix '||' used in compound expressions. I later clarified the difference in the follow up email. Mark -W The 'or' CE can result in two rules firing, if they are not mutually exclusive logical conditions. ___ 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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Well.. I don't know.. I am just asking whether that's correct or not. But it seems it's not correct... I don't know if I really need to retract facts when we are using stateless Kn. Because the session will be expired as soon as the it exists the execute() method... But I don't know why we are getting OutOfMemoryError! laune wrote The combination of a stateLESS session and this particular handling of the RuleFlowGroupDeactivatedEvent looks strange to me. Consider that after this code executes, all facts are gone, but a stateLESS session can't be populated with fresh facts, since after the return from the execute(.) call, the session itself is a goner, having been dispose()-d automatically. -W -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022603.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Hi Guys... I attached the result from profiler after it failed with OutOfMemoryError... I thought it might be helpful. I can't see our objects are the cause of this problem. This image shows instances of Drools : http://drools.46999.n3.nabble.com/file/n4022604/drools.png This image shows all instances: http://drools.46999.n3.nabble.com/file/n4022604/drools-all-object.png Our instances in memory: http://drools.46999.n3.nabble.com/file/n4022604/drools-our-objectst.png -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022604.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
What are your JVM settings? If you got an OOME/GCE when ~32Mb of live char[] were occupying ~25% of your memory, I'd suspect that you are running your application with a maximum heap size of 128M... On 02/26/2013 08:55 PM, ismaximum wrote: Hi Guys... I attached the result from profiler after it failed with OutOfMemoryError... I thought it might be helpful. I can't see our objects are the cause of this problem. This image shows instances of Drools : http://drools.46999.n3.nabble.com/file/n4022604/drools.png This image shows all instances: http://drools.46999.n3.nabble.com/file/n4022604/drools-all-object.png Our instances in memory: http://drools.46999.n3.nabble.com/file/n4022604/drools-our-objectst.png -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022604.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 25 Feb 2013, at 06:46, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Mark Proctor mproc...@codehaus.org wrote: when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) same here Are you sure you want 'or' and not ||. Mark, how would you suggest to avoid 'or' and use '||' (and I don't mean the deprecated alternative to 'or')? You are beginning to confuse (even) me! Many people do not want CE 'or' they want infix '||' used in compound expressions. I later clarified the difference in the follow up email. Mark -W The 'or' CE can result in two rules firing, if they are not mutually exclusive logical conditions. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Hi guys... We have hundreds of rules and We have this problem as well. We get either OutOfMemoryError or GC Overhead Limit Exceeded, no matter I cache kknowledgebase or create a new one. The only difference is that with caching knowledge-base it runs faster. I even increased PermGen to 768 but no lock! -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022583.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Not sure about this but I found this code in dispose() method in stateful session: this.session.dispose(); this.session = DisposedReteooWorkingMemory.INSTANCE; That means that the created session will never become eligible to be GCed, instead it remains in memory pointing to the same instance (an instance of DisposedReteooWorkingMemory) I could be wrong... please correct me if I'm wrong! -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022585.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
The GC uses **incoming** references to determine the liveness of an object and thus its eligibility for GC. The code here makes sure that the internal ReteooStatefulSession is no longer referenced by the StatefulKnowldegeSessionImpl wrapper, making it eligible for GC unless it's referenced somewhere else. The StatefulKnowledgeSessionImpl itself now may or may not be reachable anymore, depending on who was holding references to it. In any case, it is now pointing to the Disposed singleton, a mock, shared empty object. This said, you will need to provide more details about your configuration and usage. Just knowing that you have hundreds of rules does not help much in diagnosing the problem... :) Did your system work, say, in 5.4 and then started generating these OOMEs after moving to 5.5? Could the problem be reproduced systematically? What are your policies for retracting facts OR expiring sessions? See the previous messages in this thread for a list of other questions you may want to answer... Only then we may be able to provide some advice :) Best Davide On 02/25/2013 09:35 PM, ismaximum wrote: Not sure about this but I found this code in dispose() method in stateful session: this.session.dispose(); this.session = DisposedReteooWorkingMemory.INSTANCE; That means that the created session will never become eligible to be GCed, instead it remains in memory pointing to the same instance (an instance of DisposedReteooWorkingMemory) I could be wrong... please correct me if I'm wrong! -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022585.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Well, actually we are migrating from 4.x to 5.5, a big jump :) So far we had a lot of issue with this migration and now this is occurring. We had no issue with v4 and since we are still working on this migration I can't say whether the system works properly or not because we need to fix rules otherwise they don't work at all. We are using Stateless sessions and we don't have any retracting policy. This retracting policy you said, made me a bit concerned. Now the question is where is the right place to do this? I put below code in the event listener, is that the right place and right way to do it? @Override public void afterRuleFlowGroupDeactivated( org.drools.event.rule.RuleFlowGroupDeactivatedEvent e) { CollectionFactHandle handlers = e.getKnowledgeRuntime().getFactHandles(); if(handlers != null) { for(FactHandle fh : handlers) { e.getKnowledgeRuntime().retract(fh); } } } Thanks -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022587.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
The combination of a stateLESS session and this particular handling of the RuleFlowGroupDeactivatedEvent looks strange to me. Consider that after this code executes, all facts are gone, but a stateLESS session can't be populated with fresh facts, since after the return from the execute(.) call, the session itself is a goner, having been dispose()-d automatically. -W On 26/02/2013, ismaximum mnr...@gmail.com wrote: Well, actually we are migrating from 4.x to 5.5, a big jump :) So far we had a lot of issue with this migration and now this is occurring. We had no issue with v4 and since we are still working on this migration I can't say whether the system works properly or not because we need to fix rules otherwise they don't work at all. We are using Stateless sessions and we don't have any retracting policy. This retracting policy you said, made me a bit concerned. Now the question is where is the right place to do this? I put below code in the event listener, is that the right place and right way to do it? @Override public void afterRuleFlowGroupDeactivated( org.drools.event.rule.RuleFlowGroupDeactivatedEvent e) { CollectionFactHandle handlers = e.getKnowledgeRuntime().getFactHandles(); if(handlers != null) { for(FactHandle fh : handlers) { e.getKnowledgeRuntime().retract(fh); } } } Thanks -- View this message in context: http://drools.46999.n3.nabble.com/rules-users-GC-Overhead-Limit-Exceeded-and-1B-JoinLeftNode-Objects-tp4022365p4022587.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Thanks for all the advice once again. I understand their is a distinct possibility that my rules are highly inefficient and therefore leading to a large memory requirement. I will keep pairing this down to one thread and one use case. So here are two example rules I have. This demonstrates the approach I am using (pattern matching, temporal reasoning, regex matches, etc). You'll notice that rule 001n only fires when 001d exists. It is operating on a separate agenda as well. I am not sure that makes sense, but it will come down to whether a Stateless with Sequential mode is better for my scenarios than a Stateful session with one agenda (or two with the agenda being switched after the first call to fireAllRules). For reference, durationCycleYear and utils are globals. One is a I can see at the least that I need to move some variables to the right hand side of the == statements. Most of the rules are similar in their approach. rule 001 [d] @id(001d) agenda-group 'd-rules-agenda' when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) then insert(utils.saveAndReturnEvent(kcontext, $sv2)); end rule 001 [n] @id(001n) agenda-group 'n-rules-agenda' when $event : Event( externalID == 001d) $encD : SiteVisit($event.svID == ID) $inspector : Inspector (ID == $svD.inspectorID) $svN : SiteVisit( datetimeRecorded after[0ms, 90d] $svD.datetimeRecorded, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $svN.inspectorID, EUID == $inspector.EUID) FaultCode($svN.ID == svID, code matches 361.\\d+|362.4[23]|371.\\d+|360.0\\d?|360.1|362.53|998.82|998.9 ) then insert(utils.saveAndReturnEvent(kcontext, $svN)); end On Sun, Feb 24, 2013 at 1:25 AM, Mark Proctor mproc...@codehaus.org wrote: You also need to give us some indication of what your rules look like. Are you using just patterns, what conditional elements are you using, are you using any temporal operators, scheduling, tms? Mark On 24 Feb 2013, at 06:12, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. Don't change things when you try to narrow down one effect. A stateful session lets you inspect things after fireAllRules has returned. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it. Thanks. 7) Does this only apply with a shared KnowledgeBase? What if I spawn multiple sessions in separate threads? Don't do this when trying to find a memory leak. Originally I got the impression you were running sessions one after the other until running out of memory. Running jmap between sessions will give you a clear indication of what is left over after dispose(). A jmap is useful to observe trends, and I don't think only JoinNodeLeftTuple grows with the number of past sessions - don't just look at the highrunner. Compare its results after 10, 100, 1000,... single-threaded executions of identical sessions. -W All in all, I reduced the allocated heap size and ran jmap as recommended by Wolfgang with a 6GB heap, 4 threads running sessions via a ForkJoinPool and less than 100K facts. Here is a snapshot of the top hits. I ran this multiple times, and just like JProfiler, the JoinNodeLeftTuple continue to grow and grow. I would expect this to fluctuate up and down in count and size since I am not re-using a session. Not being familiar with the internals of Drools, I am hoping someone could provide a sense of whether
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Below are some comments on rules 001 [d] and 001[n] . I have silently ignored all the obvious spelling errors. On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Thanks for all the advice once again. I understand their is a distinct possibility that my rules are highly inefficient and therefore leading to a large memory requirement. I will keep pairing this down to one thread and one use case. So here are two example rules I have. This demonstrates the approach I am using (pattern matching, temporal reasoning, regex matches, etc). You'll notice that rule 001n only fires when 001d exists. It is operating on a separate agenda as well. I am not sure that makes sense, but it will come down to whether a Stateless with Sequential mode is better for my scenarios than a Stateful session with one agenda (or two with the agenda being switched after the first call to fireAllRules). For reference, durationCycleYear and utils are globals. One is a I can see at the least that I need to move some variables to the right hand side of the == statements. Most of the rules are similar in their approach. rule 001 [d] @id(001d) agenda-group 'd-rules-agenda' when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) Hopefully durationCycleYear is a global and constant? FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) In these patterns, is '.' supposed to match any character? A literal '.' would have to be escaped. $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) Bad. This matches any other SiteVisit according to these constraints, but it also matches the same one as already matched $sv1. Moreover, if there is a pair of two matching SiteVisits (SV1, SV2) there will be 4 activations with SV1+SV2, SV2+SV1, SV1+SV1, SV2+SV2. #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) This constraint should be added in the second SiteVisit pattern. There's really no need to re-bind the same Inspector - we already have it bound to $inspector. ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) then insert(utils.saveAndReturnEvent(kcontext, $sv2)); (Let's hope that the returned Event is a slim Pojo and doesn't try to conserve tons of data from kcontext.) rule 001 [n] @id(001n) agenda-group 'n-rules-agenda' when $event : Event( externalID == 001d) $encD : SiteVisit($event.svID == ID) $inspector : Inspector (ID == $svD.inspectorID) $svN : SiteVisit( datetimeRecorded after[0ms, 90d] $svD.datetimeRecorded, !annualVisit ) Note that A after[0ms,...] B does not enforce that A and B are different. See the previous comment starting with Bad.. #make sure we are dealing with the same inspector Inspector (ID == $svN.inspectorID, EUID == $inspector.EUID) See the corresponding comment re the 1st rule. FaultCode($svN.ID == svID, code matches 361.\\d+|362.4[23]|371.\\d+|360.0\\d?|360.1|362.53|998.82|998.9 ) Again: '.'? then insert(utils.saveAndReturnEvent(kcontext, $svN)); end Doesn't look too good, IMHO. A thorough revision of your rule base appears indicated. -W On Sun, Feb 24, 2013 at 1:25 AM, Mark Proctor mproc...@codehaus.org wrote: You also need to give us some indication of what your rules look like. Are you using just patterns, what conditional elements are you using, are you using any temporal operators, scheduling, tms? Mark On 24 Feb 2013, at 06:12, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. Don't change things when you try to narrow down one effect. A stateful session lets you inspect things after fireAllRules has returned. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it.
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Sorry for the typos. I rewrote the domain to save me some trouble. 1) durationCycleYear is a constant globals value 2) I see what you mean regarding the literal . in the regular expressions. It should be a literal (366\.\\d+|743\.3\\d?) . I'll see about reducing activations and unneeded optionals in these patterns. 3) Regarding the four activations with SiteVisits. I believe this is desired as the second site visit may or may not be the same visit as the first. We want to capture both scenarios. This is also potentially a complex data cleansing issue. I don't have many options here AFAICT. 4) Finding the same inspector, good point. This a data cleansing issue. I'll think about options upstream. 5) The return event that inspects the kcontext, is a slim one and does not have a reference to kcontext in it. It only has about five, non-composite fields. Thank you so very much! ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 24 Feb 2013, at 18:07, Julian Klein juliankl...@gmail.com wrote: Thanks for all the advice once again. I understand their is a distinct possibility that my rules are highly inefficient and therefore leading to a large memory requirement. I will keep pairing this down to one thread and one use case. So here are two example rules I have. This demonstrates the approach I am using (pattern matching, temporal reasoning, regex matches, etc). You'll notice that rule 001n only fires when 001d exists. It is operating on a separate agenda as well. I am not sure that makes sense, but it will come down to whether a Stateless with Sequential mode is better for my scenarios than a Stateful session with one agenda (or two with the agenda being switched after the first call to fireAllRules). For reference, durationCycleYear and utils are globals. One is a I can see at the least that I need to move some variables to the right hand side of the == statements. Most of the rules are similar in their approach. rule 001 [d] @id(001d) agenda-group 'd-rules-agenda' when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) This is wrong if you want indexing. It'll work, it just doesn't get picked up by the indexer: FaultCode( svID == $sv1.ID) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) same here Are you sure you want 'or' and not ||. The 'or' CE can result in two rules firing, if they are not mutually exclusive logical conditions. then insert(utils.saveAndReturnEvent(kcontext, $sv2)); end rule 001 [n] @id(001n) agenda-group 'n-rules-agenda' when $event : Event( externalID == 001d) $encD : SiteVisit($event.svID == ID) $inspector : Inspector (ID == $svD.inspectorID) $svN : SiteVisit( datetimeRecorded after[0ms, 90d] $svD.datetimeRecorded, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $svN.inspectorID, EUID == $inspector.EUID) FaultCode($svN.ID == svID, code matches 361.\\d+|362.4[23]|371.\\d+|360.0\\d?|360.1|362.53|998.82|998.9 ) then insert(utils.saveAndReturnEvent(kcontext, $svN)); end On Sun, Feb 24, 2013 at 1:25 AM, Mark Proctor mproc...@codehaus.org wrote: You also need to give us some indication of what your rules look like. Are you using just patterns, what conditional elements are you using, are you using any temporal operators, scheduling, tms? Mark On 24 Feb 2013, at 06:12, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. Don't change things when you try to narrow down one effect. A stateful session lets you inspect things after fireAllRules has returned. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it. Thanks. 7) Does this only apply with a shared KnowledgeBase? What if I spawn multiple sessions in separate threads? Don't do this when trying to find a memory leak. Originally I got the impression you were running sessions one after the other until running out of memory. Running jmap between sessions will give you a clear indication of what is left over after dispose(). A jmap is useful to observe trends, and I don't think only JoinNodeLeftTuple grows with the number of past sessions - don't just look at the highrunner. Compare its results after 10, 100, 1000,... single-threaded executions of identical sessions. -W All in all, I reduced the allocated heap size and ran jmap as recommended by Wolfgang with a 6GB heap, 4 threads
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
As far as $sv.ID == svID, I understand and have changed that throughout my rules. I've actually applied all your advice so far, thank you. I am still reviewing the rule base as I continue to get OoM Exceptions. I also have changed the structure of my model to reduce redundancy in the Inspector facts. This has shortened my rules a bit. In regards to or versus ||, the 5.5 docs state that || is deprecated for CEs. Therefore I chose ||. Also, if I match on either ServiceCode or FaultCode, I should get a result. I am not sure how || or or makes a difference here since the docs state they are interchangeable. Would it result in a shortcut preventing both generated sub-rules from firing? On Sun, Feb 24, 2013 at 3:50 PM, Mark Proctor mproc...@codehaus.org wrote: On 24 Feb 2013, at 18:07, Julian Klein juliankl...@gmail.com wrote: Thanks for all the advice once again. I understand their is a distinct possibility that my rules are highly inefficient and therefore leading to a large memory requirement. I will keep pairing this down to one thread and one use case. So here are two example rules I have. This demonstrates the approach I am using (pattern matching, temporal reasoning, regex matches, etc). You'll notice that rule 001n only fires when 001d exists. It is operating on a separate agenda as well. I am not sure that makes sense, but it will come down to whether a Stateless with Sequential mode is better for my scenarios than a Stateful session with one agenda (or two with the agenda being switched after the first call to fireAllRules). For reference, durationCycleYear and utils are globals. One is a I can see at the least that I need to move some variables to the right hand side of the == statements. Most of the rules are similar in their approach. rule 001 [d] @id(001d) agenda-group 'd-rules-agenda' when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) This is wrong if you want indexing. It'll work, it just doesn't get picked up by the indexer: FaultCode( svID == $sv1.ID) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) same here Are you sure you want 'or' and not ||. The 'or' CE can result in two rules firing, if they are not mutually exclusive logical conditions. then insert(utils.saveAndReturnEvent(kcontext, $sv2)); end rule 001 [n] @id(001n) agenda-group 'n-rules-agenda' when $event : Event( externalID == 001d) $encD : SiteVisit($event.svID == ID) $inspector : Inspector (ID == $svD.inspectorID) $svN : SiteVisit( datetimeRecorded after[0ms, 90d] $svD.datetimeRecorded, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $svN.inspectorID, EUID == $inspector.EUID) FaultCode($svN.ID == svID, code matches 361.\\d+|362.4[23]|371.\\d+|360.0\\d?|360.1|362.53|998.82|998.9 ) then insert(utils.saveAndReturnEvent(kcontext, $svN)); end On Sun, Feb 24, 2013 at 1:25 AM, Mark Proctor mproc...@codehaus.orgwrote: You also need to give us some indication of what your rules look like. Are you using just patterns, what conditional elements are you using, are you using any temporal operators, scheduling, tms? Mark On 24 Feb 2013, at 06:12, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. Don't change things when you try to narrow down one effect. A stateful session lets you inspect things after fireAllRules has returned. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it. Thanks. 7) Does
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 24 Feb 2013, at 21:57, Julian Klein juliankl...@gmail.com wrote: As far as $sv.ID == svID, I understand and have changed that throughout my rules. I've actually applied all your advice so far, thank you. I am still reviewing the rule base as I continue to get OoM Exceptions. I also have changed the structure of my model to reduce redundancy in the Inspector facts. This has shortened my rules a bit. In regards to or versus ||, the 5.5 docs state that || is deprecated for CEs. Therefore I chose ||. '||' is deprecated between CE's, so that it can be used for inside of expressions. Early versions of drools did not have compound expressions, it only supported conditional element or. Later we added compound expression. The behaviour of a CE 'or' and a compound expression are different. the 'or' CE is removed and logical rewrite rules applied to create rules for each possible outcome. The result is you can have multiple rules firing. Also, if I match on either ServiceCode or FaultCode, I should get a result. I am not sure how || or or makes a difference here since the docs state they are interchangeable. Would it result in a shortcut preventing both generated sub-rules from firing? The docs differentiate between 'or' CE and || compound expression. MArk On Sun, Feb 24, 2013 at 3:50 PM, Mark Proctor mproc...@codehaus.org wrote: On 24 Feb 2013, at 18:07, Julian Klein juliankl...@gmail.com wrote: Thanks for all the advice once again. I understand their is a distinct possibility that my rules are highly inefficient and therefore leading to a large memory requirement. I will keep pairing this down to one thread and one use case. So here are two example rules I have. This demonstrates the approach I am using (pattern matching, temporal reasoning, regex matches, etc). You'll notice that rule 001n only fires when 001d exists. It is operating on a separate agenda as well. I am not sure that makes sense, but it will come down to whether a Stateless with Sequential mode is better for my scenarios than a Stateful session with one agenda (or two with the agenda being switched after the first call to fireAllRules). For reference, durationCycleYear and utils are globals. One is a I can see at the least that I need to move some variables to the right hand side of the == statements. Most of the rules are similar in their approach. rule 001 [d] @id(001d) agenda-group 'd-rules-agenda' when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) This is wrong if you want indexing. It'll work, it just doesn't get picked up by the indexer: FaultCode( svID == $sv1.ID) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) same here Are you sure you want 'or' and not ||. The 'or' CE can result in two rules firing, if they are not mutually exclusive logical conditions. then insert(utils.saveAndReturnEvent(kcontext, $sv2)); end rule 001 [n] @id(001n) agenda-group 'n-rules-agenda' when $event : Event( externalID == 001d) $encD : SiteVisit($event.svID == ID) $inspector : Inspector (ID == $svD.inspectorID) $svN : SiteVisit( datetimeRecorded after[0ms, 90d] $svD.datetimeRecorded, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $svN.inspectorID, EUID == $inspector.EUID) FaultCode($svN.ID == svID, code matches 361.\\d+|362.4[23]|371.\\d+|360.0\\d?|360.1|362.53|998.82|998.9 ) then insert(utils.saveAndReturnEvent(kcontext, $svN)); end On Sun, Feb 24, 2013 at 1:25 AM, Mark Proctor mproc...@codehaus.org wrote: You also need to give us some indication of what your rules look like. Are you using just patterns, what conditional elements are you using, are you using any temporal operators, scheduling, tms? Mark On 24 Feb 2013, at 06:12, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession.
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 24/02/2013, Mark Proctor mproc...@codehaus.org wrote: when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( $sv1.ID==svID, code matches 366.\\d+|743.3\\d? ) $inspector: Insepector (ID == $sv1.insepectortID) $sv2 : SitVisit( yearRecorded == durationCycleYear, !annualVisit ) #make sure we are dealing with the same inspector Inspector (ID == $sv2.inspectorID, EUID == $inspector.EUID) ( FaultCode( $sv2.ID == svID, code matches 45.61 ) or ServiceCode($sv2.ID == svID, code matches 66(8[4-9][0-9]|9([0-3][0-9]|40))|66982|66984|66983 ) ) same here Are you sure you want 'or' and not ||. Mark, how would you suggest to avoid 'or' and use '||' (and I don't mean the deprecated alternative to 'or')? You are beginning to confuse (even) me! -W The 'or' CE can result in two rules firing, if they are not mutually exclusive logical conditions. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: 2) I see what you mean regarding the literal . in the regular expressions. It should be a literal (366\.\\d+|743\.3\\d?) . 366\\.\\d+|743\\.\\d? 3) Regarding the four activations with SiteVisits. I believe this is desired as the second site visit may or may not be the same visit as the first. [Hmm, words like first and second imply two distinct events, so they can't be the same. You may have a mess in your data so that there could be two reports (!) of the *same* visit.] We want to capture both scenarios. This is also potentially a complex data cleansing issue. I don't have many options here AFAICT. I'd say it's a get-your-specs-cleansed issue. Consider the rule (after eliminating the useless binding of Inspector and some simplifications): when $sv1 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit ) FaultCode( svID == $sv1.ID, code matches 366.12 ) $sv2 : SiteVisit( yearRecorded == durationCycleYear, !annualVisit, inspectorID == $sv1.inspectorID ) // ensure same Inspector FaultCode( svID == $sv2.ID, code matches 45.61 ) then Now, not knowing how SiteVisit and FaultCode can be related, I can only guess that possible data could be: (1) SiteVisit( 2013, 13/42, false ) // year, ID, annualVisit FaultCode( 366.12, 13/42 ) SiteVisit( 2013, 13/55, false ) FaultCode( 45.61, 13/55 ) Two distinct visits, fires once. (2) SiteVisit( 2013, 13/42, false ) FaultCode( 366.12, 13/42 ) FaultCode( 45.61, 13/42 ) There is only one visit, but fires once nonetheless. (3) SiteVisit( 2013, 13/42, false ) FaultCode( 366.12, 13/42 ) FaultCode( 45.61, 13/42 ) SiteVisit( 2013, 13/55, false ) FaultCode( 366.12, 13/55 ) FaultCode( 45.61, 13/55 ) Two visits, fires twice. It's possible that multiple FaultCodes per SiteVisit aren't possible, but the data model (AFAIK) suggests otherwise, and if this is so, you should be prepared for every possible situation. I can't imagine handling all three situations adequately with this single rule. 4) Finding the same inspector, good point. This a data cleansing issue. I'll think about options upstream. No, it is definitely not data cleansing - it is an issue of writing rules well. (Sorry for the harsh wording.) -W ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Although I did see a drop in initial memory usage, things went south again as the run continued past the 2-4 hour mark. I have poured over my source several times and am starting to loose faith that Drools can provide anything other than a single threaded rules engine. Although the engine itself is fast, it seems it cannot scale from a memory perspective. I understand I am not providing much detail or a use case, but perhaps there are some official best practices documented somewhere on how to scale Drools? I cannot get valuable heap dumps because the heaps are enormous. I have continuously been told that Drools doesn't perform by colleagues and was hoping they were wrong. Any pointers or help is greatly appreciated. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Typical issues are: 1) Not retracting facts, or setting expiration. 2) Not disposing sessions. 3) Poor discrimination networks that produce too many cross products - put the strongest descriptors first. 4) Making sure you use constraints that exploit indexing (this makes a huge difference for performance) 5) Excessive recursion, cause massive memory consumption. 6) Design your rules to facilitate node sharing better. 7) Drools is single threaded, Each external thread goes through a jdk lock to ensure serial access. You need to isolate your program down to a few rules, show that it either works or has a problem. And then just build that out from there, until you can demonstrate the problem. You can't just build a large rule base, and then wonder why there are problems at the end. This is the strongest piece of advice I give to starting a rule based project - as I see this problem happen often. You should build out small and slowly, testing at each stage - for correctness and performance. That way when problems occur, you are able to isolate the problem to a small range of code commits. Never be in a hurry to rush to the finishing line, think tortoise and the hare. We have other users scaling to millions of facts and hundreds of rules, running in reasonable amount of time. We do get bugs, and we always work hard to get those isolated, but we need something to allow us to help diagnose the problem. Mark On 23 Feb 2013, at 21:10, Julian Klein juliankl...@gmail.com wrote: Although I did see a drop in initial memory usage, things went south again as the run continued past the 2-4 hour mark. I have poured over my source several times and am starting to loose faith that Drools can provide anything other than a single threaded rules engine. Although the engine itself is fast, it seems it cannot scale from a memory perspective. I understand I am not providing much detail or a use case, but perhaps there are some official best practices documented somewhere on how to scale Drools? I cannot get valuable heap dumps because the heaps are enormous. I have continuously been told that Drools doesn't perform by colleagues and was hoping they were wrong. Any pointers or help is greatly appreciated. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
This is great. It sounds like I have to go back to the drawing board. It may take a while to work through this list. I'll circle back with outcomes. Thank you. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it. Thanks. 7) Does this only apply with a shared KnowledgeBase? What if I spawn multiple sessions in separate threads? All in all, I reduced the allocated heap size and ran jmap as recommended by Wolfgang with a 6GB heap, 4 threads running sessions via a ForkJoinPool and less than 100K facts. Here is a snapshot of the top hits. I ran this multiple times, and just like JProfiler, the JoinNodeLeftTuple continue to grow and grow. I would expect this to fluctuate up and down in count and size since I am not re-using a session. Not being familiar with the internals of Drools, I am hoping someone could provide a sense of whether or not the below points to one of the issues Mark mentioned above. Also, during GC events only Eden space gets freed up so these objects appear to be living in Tenured space. This further concerns me that something is not being cleaned up. I fear it is all not so simple and will continue looking into Mark's list for opportunities in my code base as well as work towards simple test case. I appreciate all the time taken to read my rather lengthy emails. I am hoping that this detail will help others as it has me. Thank you. num #instances #bytes class name -- 1: 61754567 4940365360 org.drools.reteoo.JoinNodeLeftTuple 2: 1954644 109460064 org.drools.reteoo.RightTuple 3:302247 24179760 org.drools.common.AgendaItem 4:447814 21495072 com.mycompany.loader.FactsLoader - A bunch of callable objects that get executed to load data to send to Drools when the processor(s) is (are) idle. 5:302247 19343808 org.drools.reteoo.RuleTerminalNodeLeftTuple 6:897091 14353456 java.lang.Integer 7:447814 14330048 java.util.RandomAccessSubList 8:300383 11743152 [C 9:447815 10747560 java.util.Collections$SynchronizedRandomAccessList On Sat, Feb 23, 2013 at 5:57 PM, Julian Klein juliankl...@gmail.com wrote: This is great. It sounds like I have to go back to the drawing board. It may take a while to work through this list. I'll circle back with outcomes. Thank you. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 24 Feb 2013, at 04:11, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. it makes no difference. Stateless is just a convenience wrapper for stateful, that avoids having to call dispose at the end. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. Don't let an application get this big, before you start testing. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. no not everything is indexed. Only '==' operators are indexed, and you must put the field name to the left of the operator. Until recently anything with nested accessors would not be indexed either, but that should have improved in 5.5 5) Since I am using a stateless session, I would expect no recursion. Statless session is just a wrapper for stateful. If the consequences modify or insert data, you get recursions. 6) Got it. Thanks. 7) Does this only apply with a shared KnowledgeBase? What if I spawn multiple sessions in separate threads? The thread lock is per session. All in all, I reduced the allocated heap size and ran jmap as recommended by Wolfgang with a 6GB heap, 4 threads running sessions via a ForkJoinPool and less than 100K facts. Here is a snapshot of the top hits. I ran this multiple times, and just like JProfiler, the JoinNodeLeftTuple continue to grow and grow. I would expect this to fluctuate up and down in count and size since I am not re-using a session. Not being familiar with the internals of Drools, I am hoping someone could provide a sense of whether or not the below points to one of the issues Mark mentioned above. Also, during GC events only Eden space gets freed up so these objects appear to be living in Tenured space. This further concerns me that something is not being cleaned up. I fear it is all not so simple and will continue looking into Mark's list for opportunities in my code base as well as work towards simple test case. I appreciate all the time taken to read my rather lengthy emails. I am hoping that this detail will help others as it has me. Thank you. num #instances #bytes class name -- 1: 61754567 4940365360 org.drools.reteoo.JoinNodeLeftTuple 2: 1954644 109460064 org.drools.reteoo.RightTuple 3:302247 24179760 org.drools.common.AgendaItem 4:447814 21495072 com.mycompany.loader.FactsLoader - A bunch of callable objects that get executed to load data to send to Drools when the processor(s) is (are) idle. 5:302247 19343808 org.drools.reteoo.RuleTerminalNodeLeftTuple 6:897091 14353456 java.lang.Integer 7:447814 14330048 java.util.RandomAccessSubList 8:300383 11743152 [C 9:447815 10747560 java.util.Collections$SynchronizedRandomAccessList On Sat, Feb 23, 2013 at 5:57 PM, Julian Klein juliankl...@gmail.com wrote: This is great. It sounds like I have to go back to the drawing board. It may take a while to work through this list. I'll circle back with outcomes. Thank you. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. Don't change things when you try to narrow down one effect. A stateful session lets you inspect things after fireAllRules has returned. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it. Thanks. 7) Does this only apply with a shared KnowledgeBase? What if I spawn multiple sessions in separate threads? Don't do this when trying to find a memory leak. Originally I got the impression you were running sessions one after the other until running out of memory. Running jmap between sessions will give you a clear indication of what is left over after dispose(). A jmap is useful to observe trends, and I don't think only JoinNodeLeftTuple grows with the number of past sessions - don't just look at the highrunner. Compare its results after 10, 100, 1000,... single-threaded executions of identical sessions. -W All in all, I reduced the allocated heap size and ran jmap as recommended by Wolfgang with a 6GB heap, 4 threads running sessions via a ForkJoinPool and less than 100K facts. Here is a snapshot of the top hits. I ran this multiple times, and just like JProfiler, the JoinNodeLeftTuple continue to grow and grow. I would expect this to fluctuate up and down in count and size since I am not re-using a session. Not being familiar with the internals of Drools, I am hoping someone could provide a sense of whether or not the below points to one of the issues Mark mentioned above. Also, during GC events only Eden space gets freed up so these objects appear to be living in Tenured space. This further concerns me that something is not being cleaned up. I fear it is all not so simple and will continue looking into Mark's list for opportunities in my code base as well as work towards simple test case. I appreciate all the time taken to read my rather lengthy emails. I am hoping that this detail will help others as it has me. Thank you. num #instances #bytes class name -- 1: 61754567 4940365360 org.drools.reteoo.JoinNodeLeftTuple 2: 1954644 109460064 org.drools.reteoo.RightTuple 3:302247 24179760 org.drools.common.AgendaItem 4:447814 21495072 com.mycompany.loader.FactsLoader - A bunch of callable objects that get executed to load data to send to Drools when the processor(s) is (are) idle. 5:302247 19343808 org.drools.reteoo.RuleTerminalNodeLeftTuple 6:897091 14353456 java.lang.Integer 7:447814 14330048 java.util.RandomAccessSubList 8:300383 11743152 [C 9:447815 10747560 java.util.Collections$SynchronizedRandomAccessList On Sat, Feb 23, 2013 at 5:57 PM, Julian Klein juliankl...@gmail.com wrote: This is great. It sounds like I have to go back to the drawing board. It may take a while to work through this list. I'll circle back with outcomes. Thank you. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
You also need to give us some indication of what your rules look like. Are you using just patterns, what conditional elements are you using, are you using any temporal operators, scheduling, tms? Mark On 24 Feb 2013, at 06:12, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 24/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, thanks. Here's what I have so far: 1) I am not retracting facts or setting expiration. This is by design since I am doing the next item. Do I need to retract globals? Be careful with globals when you run alike sessions in parallel - the object(s) is (are) shared. 2) I have disposed the session when I ran with a StatefulSession. I understood this means I do not need to retract facts. I do not attempt to reuse the session. I am now trying to use a StatelessSession. Don't change things when you try to narrow down one effect. A stateful session lets you inspect things after fireAllRules has returned. 3) Unfortunately, the rule base is very large and this will take a long time. I am hoping to at least get to a point where this runs end-to-end. If it takes several hours, I am ok with that. 4) I would expect everything except eval statements to take advantage of indexing in my rules. Are you talking about BetaNode indexing? In all cases, I use the property access over getters. 5) Since I am using a stateless session, I would expect no recursion. 6) Got it. Thanks. 7) Does this only apply with a shared KnowledgeBase? What if I spawn multiple sessions in separate threads? Don't do this when trying to find a memory leak. Originally I got the impression you were running sessions one after the other until running out of memory. Running jmap between sessions will give you a clear indication of what is left over after dispose(). A jmap is useful to observe trends, and I don't think only JoinNodeLeftTuple grows with the number of past sessions - don't just look at the highrunner. Compare its results after 10, 100, 1000,... single-threaded executions of identical sessions. -W All in all, I reduced the allocated heap size and ran jmap as recommended by Wolfgang with a 6GB heap, 4 threads running sessions via a ForkJoinPool and less than 100K facts. Here is a snapshot of the top hits. I ran this multiple times, and just like JProfiler, the JoinNodeLeftTuple continue to grow and grow. I would expect this to fluctuate up and down in count and size since I am not re-using a session. Not being familiar with the internals of Drools, I am hoping someone could provide a sense of whether or not the below points to one of the issues Mark mentioned above. Also, during GC events only Eden space gets freed up so these objects appear to be living in Tenured space. This further concerns me that something is not being cleaned up. I fear it is all not so simple and will continue looking into Mark's list for opportunities in my code base as well as work towards simple test case. I appreciate all the time taken to read my rather lengthy emails. I am hoping that this detail will help others as it has me. Thank you. num #instances #bytes class name -- 1: 61754567 4940365360 org.drools.reteoo.JoinNodeLeftTuple 2: 1954644 109460064 org.drools.reteoo.RightTuple 3:302247 24179760 org.drools.common.AgendaItem 4:447814 21495072 com.mycompany.loader.FactsLoader - A bunch of callable objects that get executed to load data to send to Drools when the processor(s) is (are) idle. 5:302247 19343808 org.drools.reteoo.RuleTerminalNodeLeftTuple 6:897091 14353456 java.lang.Integer 7:447814 14330048 java.util.RandomAccessSubList 8:300383 11743152 [C 9:447815 10747560 java.util.Collections$SynchronizedRandomAccessList On Sat, Feb 23, 2013 at 5:57 PM, Julian Klein juliankl...@gmail.com wrote: This is great. It sounds like I have to go back to the drawing board. It may take a while to work through this list. I'll circle back with outcomes. Thank you. ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Ok, so I reviewed my code again and found a spot where I am queuing up tasks to process data that hadn't been loaded. My application shouldn't spawn a rule sessions in the case. I have also moved to a sever with less RAM and will begin profiling as soon as possible. Here is where I stand as of now: 1) I am still seeing about 250 million JoinNodeLeftTuples (eats up about 30GB of RAM). This greatly outnumbers anything else in the system by a factor of 100x. 2) Creating a test case will be very difficult as I cannot pinpoint the root cause of this issue. I am not sure if it is related to too many rules engine, the size of my ruleset, or simply the scale at which I am attempting to use Drools. If I pinpoint an actual memory leak, I will create a test case and submit. 3) I cannot use a StatelessKnowledgeSession as it locks my process up. It seems the code in StatelessKnowledgeSessionImpl's constructor creates a lock that never releases. No idea on this either for now. this.ruleBase.lock(); try { if ( ruleBase.getConfiguration().isSequential() ) { this.ruleBase.getReteooBuilder().order(); } } finally { *this.ruleBase.unlock(); --- This line is never reached for some reason* } I will continue trying to find a root cause or path forward and report back. If anything here gives you all a sense of some wrongdoing on my behalf, please let me know. I don't fully understand sequential mode as the documentation is not approachable from my uninformed perspective. So perhaps there is something I am doing in my rules that leads to this lock not getting release? Thanks again, Julian On Mon, Feb 18, 2013 at 9:13 AM, Julian Klein juliankl...@gmail.com wrote: Unfortunately the server I was using locked up last night and I cannot get access. I'll have to find an interim system where I can run tests and profile the heap. In the meantime, I switched to a Sequential Stateless Session. I don't know the internals of Drools, but since this seems to turn off the left input propagation, does that mean the JoinLeftNode is not used? I am running 5.4 .0 on Linux. If I see the same issues with a stateless approach, I will try the 5.5 approach. Thanks again, Julian On Feb 17, 2013, at 6:19 PM, Mark Proctor mproc...@codehaus.org wrote: You'll need to help us a bit here, by creating a test of some sort. I have 100 rules with 1B JoinLeftNode doesn't give us much to go on. The problem mentioned earlier was related to windows, which I don't think you are using - or you'd have said so. Also can you tell us what version you are using? Could you maybe try the 5..5.x branch which has a lot of fixes in it (you'll need to build it with maven): https://github.com/droolsjbpm/drools/tree/5.5.x mark On 17 Feb 2013, at 18:27, Julian Klein juliankl...@gmail.com wrote: Thanks again. I have tried Sequential mode, but somehow my Java based class that I use for function calls no longer receives them. Perhaps there is an error occurring before the call to my class in the then section of the rule that is not presenting itself in my logs. Either that or I don't understand sequential mode's limitations well enough. I'll try it one more time and report back on that as well. On Sun, Feb 17, 2013 at 1:17 PM, Wolfgang Laun wolfgang.l...@gmail.comwrote: On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? If you need to start each session with a clean slate: yes, dispose is preferable. Also, would using a Stateless Session perform better from either a memory or CPU perspective? Only if you can run it in sequential mode - see Expert, 3.3.7.1. Sequential Mode -W Thanks again! ___ 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 ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 19 Feb 2013, at 15:57, Julian Klein juliankl...@gmail.com wrote: Ok, so I reviewed my code again and found a spot where I am queuing up tasks to process data that hadn't been loaded. My application shouldn't spawn a rule sessions in the case. I have also moved to a sever with less RAM and will begin profiling as soon as possible. Here is where I stand as of now: 1) I am still seeing about 250 million JoinNodeLeftTuples (eats up about 30GB of RAM). This greatly outnumbers anything else in the system by a factor of 100x. 2) Creating a test case will be very difficult as I cannot pinpoint the root cause of this issue. I am not sure if it is related to too many rules engine, the size of my ruleset, or simply the scale at which I am attempting to use Drools. If I pinpoint an actual memory leak, I will create a test case and submit. 3) I cannot use a StatelessKnowledgeSession as it locks my process up. It seems the code in StatelessKnowledgeSessionImpl's constructor creates a lock that never releases. No idea on this either for now. this.ruleBase.lock(); try { if ( ruleBase.getConfiguration().isSequential() ) { this.ruleBase.getReteooBuilder().order(); } } finally { this.ruleBase.unlock(); --- This line is never reached for some reason } I will continue trying to find a root cause or path forward and report back. If anything here gives you all a sense of some wrongdoing on my behalf, please let me know. I don't fully understand sequential mode as the documentation is not approachable from my uninformed perspective. So perhaps there is something I am doing in my rules that leads to this lock not getting release? Sequential mode means no inference. If you want to modify or insert facts and have them evaluated in the rules, then you don't want sequential mode. Thanks again, Julian On Mon, Feb 18, 2013 at 9:13 AM, Julian Klein juliankl...@gmail.com wrote: Unfortunately the server I was using locked up last night and I cannot get access. I'll have to find an interim system where I can run tests and profile the heap. In the meantime, I switched to a Sequential Stateless Session. I don't know the internals of Drools, but since this seems to turn off the left input propagation, does that mean the JoinLeftNode is not used? I am running 5.4 .0 on Linux. If I see the same issues with a stateless approach, I will try the 5.5 approach. Thanks again, Julian On Feb 17, 2013, at 6:19 PM, Mark Proctor mproc...@codehaus.org wrote: You'll need to help us a bit here, by creating a test of some sort. I have 100 rules with 1B JoinLeftNode doesn't give us much to go on. The problem mentioned earlier was related to windows, which I don't think you are using - or you'd have said so. Also can you tell us what version you are using? Could you maybe try the 5..5.x branch which has a lot of fixes in it (you'll need to build it with maven): https://github.com/droolsjbpm/drools/tree/5.5.x mark On 17 Feb 2013, at 18:27, Julian Klein juliankl...@gmail.com wrote: Thanks again. I have tried Sequential mode, but somehow my Java based class that I use for function calls no longer receives them. Perhaps there is an error occurring before the call to my class in the then section of the rule that is not presenting itself in my logs. Either that or I don't understand sequential mode's limitations well enough. I'll try it one more time and report back on that as well. On Sun, Feb 17, 2013 at 1:17 PM, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? If you need to start each session with a clean slate: yes, dispose is preferable. Also, would using a Stateless Session perform better from either a memory or CPU perspective? Only if you can run it in sequential mode - see Expert, 3.3.7.1. Sequential Mode -W Thanks again! ___ 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 ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Thanks, Mark. I am avoiding inference by storing the results of rules execution in memory and then firing the rules against those at a later point in the program execution. This workaround enables me to more directly control data flow and use a Stateless Session. In regards to my original post, I've had a breakthrough in regards to memory overhead. I switched to a StatelessKnowledgeSession and avoided the above locking condition. Please ignore the line I mentioned previously as that one is incorrect. I was getting a lock within the fireAllRules method. Anyway, I now cache the KnowledgeBuilder and create a new KnowledgeBase and Session for each thread needing to execute rules. This stopped the lock condition from occurring when firing rules as there is no shared rule base across threads. The count of JoinNodeLeftTuple objects and overall memory usage has dropped dramatically. It seems the root cause was the caching of my KnowledgeBase object for reuse and the use of a StatefulKnowledgeSession. Given the complexity of my scenario, I have been unable to create a simple use case. I suppose at this stage this begs the question of whether or not it is appropriate to cache the KnowledgeBase instead of simply the KnowledgeBuilder? I have also set the keep reference flag set to false for the session config, but something was keeping a handle on expired sessions anyway. Either that or the stateless session's footprint is several orders of magnitude smaller. Thanks. On Tue, Feb 19, 2013 at 7:08 PM, Mark Proctor mproc...@codehaus.org wrote: On 19 Feb 2013, at 15:57, Julian Klein juliankl...@gmail.com wrote: Ok, so I reviewed my code again and found a spot where I am queuing up tasks to process data that hadn't been loaded. My application shouldn't spawn a rule sessions in the case. I have also moved to a sever with less RAM and will begin profiling as soon as possible. Here is where I stand as of now: 1) I am still seeing about 250 million JoinNodeLeftTuples (eats up about 30GB of RAM). This greatly outnumbers anything else in the system by a factor of 100x. 2) Creating a test case will be very difficult as I cannot pinpoint the root cause of this issue. I am not sure if it is related to too many rules engine, the size of my ruleset, or simply the scale at which I am attempting to use Drools. If I pinpoint an actual memory leak, I will create a test case and submit. 3) I cannot use a StatelessKnowledgeSession as it locks my process up. It seems the code in StatelessKnowledgeSessionImpl's constructor creates a lock that never releases. No idea on this either for now. this.ruleBase.lock(); try { if ( ruleBase.getConfiguration().isSequential() ) { this.ruleBase.getReteooBuilder().order(); } } finally { *this.ruleBase.unlock(); --- This line is never reached for some reason* } I will continue trying to find a root cause or path forward and report back. If anything here gives you all a sense of some wrongdoing on my behalf, please let me know. I don't fully understand sequential mode as the documentation is not approachable from my uninformed perspective. So perhaps there is something I am doing in my rules that leads to this lock not getting release? Sequential mode means no inference. If you want to modify or insert facts and have them evaluated in the rules, then you don't want sequential mode. Thanks again, Julian On Mon, Feb 18, 2013 at 9:13 AM, Julian Klein juliankl...@gmail.comwrote: Unfortunately the server I was using locked up last night and I cannot get access. I'll have to find an interim system where I can run tests and profile the heap. In the meantime, I switched to a Sequential Stateless Session. I don't know the internals of Drools, but since this seems to turn off the left input propagation, does that mean the JoinLeftNode is not used? I am running 5.4 .0 on Linux. If I see the same issues with a stateless approach, I will try the 5.5 approach. Thanks again, Julian On Feb 17, 2013, at 6:19 PM, Mark Proctor mproc...@codehaus.org wrote: You'll need to help us a bit here, by creating a test of some sort. I have 100 rules with 1B JoinLeftNode doesn't give us much to go on. The problem mentioned earlier was related to windows, which I don't think you are using - or you'd have said so. Also can you tell us what version you are using? Could you maybe try the 5..5.x branch which has a lot of fixes in it (you'll need to build it with maven): https://github.com/droolsjbpm/drools/tree/5.5.x mark On 17 Feb 2013, at 18:27, Julian Klein juliankl...@gmail.com wrote: Thanks again. I have tried Sequential mode, but somehow my Java based class that I use for function calls no longer receives them. Perhaps there is an error occurring before the call to my class in the then section of the
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Unfortunately the server I was using locked up last night and I cannot get access. I'll have to find an interim system where I can run tests and profile the heap. In the meantime, I switched to a Sequential Stateless Session. I don't know the internals of Drools, but since this seems to turn off the left input propagation, does that mean the JoinLeftNode is not used? I am running 5.4 .0 on Linux. If I see the same issues with a stateless approach, I will try the 5.5 approach. Thanks again, Julian On Feb 17, 2013, at 6:19 PM, Mark Proctor mproc...@codehaus.org wrote: You'll need to help us a bit here, by creating a test of some sort. I have 100 rules with 1B JoinLeftNode doesn't give us much to go on. The problem mentioned earlier was related to windows, which I don't think you are using - or you'd have said so. Also can you tell us what version you are using? Could you maybe try the 5..5.x branch which has a lot of fixes in it (you'll need to build it with maven): https://github.com/droolsjbpm/drools/tree/5.5.x mark On 17 Feb 2013, at 18:27, Julian Klein juliankl...@gmail.com wrote: Thanks again. I have tried Sequential mode, but somehow my Java based class that I use for function calls no longer receives them. Perhaps there is an error occurring before the call to my class in the then section of the rule that is not presenting itself in my logs. Either that or I don't understand sequential mode's limitations well enough. I'll try it one more time and report back on that as well. On Sun, Feb 17, 2013 at 1:17 PM, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? If you need to start each session with a clean slate: yes, dispose is preferable. Also, would using a Stateless Session perform better from either a memory or CPU perspective? Only if you can run it in sequential mode - see Expert, 3.3.7.1. Sequential Mode -W Thanks again! ___ 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 ___ 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
[rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Hi all, I trying to run Drools Expert with varying sizes of memory, but no matter how large I go the system continues to thrown OoM Exceptions. As my application runs memory slowly, but steadily dries up. Perhaps this is related to the other recent thread regarding memory leaks? I have searched high and low in the forums with no luck on what could cause this problem. It seems like a memory leak to me at this point as I have profiled and found no problems in my code. How My App Works: Anyway, my application creates a StatefulKnowledgeSession with ~100 rules, inserts a 1000 facts, fires all rules, inserts new facts created from the first run, changes the agenda, fires rules again and then disposes the session and related resources. It does this in tight loops, thousands of times. This means there should not be 1B objects floating around in memory from Drools. I have thought of a few ways out: 1) reduce the speed at which I create and dispose rule sessions; not ideal for performance 2) re-using the session though this seems it will cause more memory issues 3) move to stateless knowledge sessions, but for some reason some of my utility functions fail with this approach. Any insight would be appreciated. Thanks, Julian ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
What about running jmap -histo:live ps after 1, 10 and 100 cycles? Just insert a sleep long enough to let you run the utility. -W On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Hi all, I trying to run Drools Expert with varying sizes of memory, but no matter how large I go the system continues to thrown OoM Exceptions. As my application runs memory slowly, but steadily dries up. Perhaps this is related to the other recent thread regarding memory leaks? I have searched high and low in the forums with no luck on what could cause this problem. It seems like a memory leak to me at this point as I have profiled and found no problems in my code. How My App Works: Anyway, my application creates a StatefulKnowledgeSession with ~100 rules, inserts a 1000 facts, fires all rules, inserts new facts created from the first run, changes the agenda, fires rules again and then disposes the session and related resources. It does this in tight loops, thousands of times. This means there should not be 1B objects floating around in memory from Drools. I have thought of a few ways out: 1) reduce the speed at which I create and dispose rule sessions; not ideal for performance 2) re-using the session though this seems it will cause more memory issues 3) move to stateless knowledge sessions, but for some reason some of my utility functions fail with this approach. Any insight would be appreciated. Thanks, Julian ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
I've attached using jprofiler before at various stages. All show more Drools objects than I would expect. Are you asking for a count at an earlier point in the application's execution? Otherwise, I am missing the point. Could you clarify? ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: I've attached using jprofiler before at various stages. All show more Drools objects than I would expect. There will be many different org.drools* classes, but if one or more of these classes participate in a memory leak, their #instances count should increase when you look at it between laps. Are you asking for a count at an earlier point in the application's execution? Otherwise, I am missing the point. Could you clarify? ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? Also, would using a Stateless Session perform better from either a memory or CPU perspective? Thanks again! ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? If you need to start each session with a clean slate: yes, dispose is preferable. Also, would using a Stateless Session perform better from either a memory or CPU perspective? Only if you can run it in sequential mode - see Expert, 3.3.7.1. Sequential Mode -W Thanks again! ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
Thanks again. I have tried Sequential mode, but somehow my Java based class that I use for function calls no longer receives them. Perhaps there is an error occurring before the call to my class in the then section of the rule that is not presenting itself in my logs. Either that or I don't understand sequential mode's limitations well enough. I'll try it one more time and report back on that as well. On Sun, Feb 17, 2013 at 1:17 PM, Wolfgang Laun wolfgang.l...@gmail.comwrote: On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? If you need to start each session with a clean slate: yes, dispose is preferable. Also, would using a Stateless Session perform better from either a memory or CPU perspective? Only if you can run it in sequential mode - see Expert, 3.3.7.1. Sequential Mode -W Thanks again! ___ 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
Re: [rules-users] GC Overhead Limit Exceeded and 1B JoinLeftNode Objects
You'll need to help us a bit here, by creating a test of some sort. I have 100 rules with 1B JoinLeftNode doesn't give us much to go on. The problem mentioned earlier was related to windows, which I don't think you are using - or you'd have said so. Also can you tell us what version you are using? Could you maybe try the 5..5.x branch which has a lot of fixes in it (you'll need to build it with maven): https://github.com/droolsjbpm/drools/tree/5.5.x mark On 17 Feb 2013, at 18:27, Julian Klein juliankl...@gmail.com wrote: Thanks again. I have tried Sequential mode, but somehow my Java based class that I use for function calls no longer receives them. Perhaps there is an error occurring before the call to my class in the then section of the rule that is not presenting itself in my logs. Either that or I don't understand sequential mode's limitations well enough. I'll try it one more time and report back on that as well. On Sun, Feb 17, 2013 at 1:17 PM, Wolfgang Laun wolfgang.l...@gmail.com wrote: On 17/02/2013, Julian Klein juliankl...@gmail.com wrote: Ok, I witnessed this with JProfiler. I will try with jmap to make sure and report back later today or tomorrow. Is it safe then to assume that discarding (dispose) the session between laps is better from a throughput perspective than re-using it? If you need to start each session with a clean slate: yes, dispose is preferable. Also, would using a Stateless Session perform better from either a memory or CPU perspective? Only if you can run it in sequential mode - see Expert, 3.3.7.1. Sequential Mode -W Thanks again! ___ 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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users