Hi,
applied to the scratchpad. Own config is missing.
I have to go to bed now ;)...

TIA
  ~Gerhard
 
"Sorry, but my karma just ran over your dogma."

>-----Original Message-----
>From: Peter Hargreaves [mailto:[EMAIL PROTECTED]]
>Sent: Tuesday, February 05, 2002 1:36 AM
>To: [EMAIL PROTECTED]
>Subject: Re: StoreJanitor new calculation [was: Re: Store Janitor Hangs
>System]
>
>
>Hi Gerhard,
>
>Great to hear that I've not been wasting my time :-)
>
>Please find attached the updated code.
>
>[EMAIL PROTECTED] wrote:
>
>> Peter,
>> 
>> 
>>>From: Peter Hargreaves [mailto:[EMAIL PROTECTED]]
>>>
>>>Hi Gerhard,
>>>
>>>I've tested your latest Store Janitor improvements (using Optimizit and 
>>>your debug messages) and although its a very great improvement, I've 
>>>found some other problems :-(
>>>
>> 
>> Damn...
>> 
>> 
>>>As my Optimizit trial was running out I decided to do some urgent work 
>>>on the Checker and now have a solution which appears to work well :-)
>>>
>>>Here is a summary of the problems with ideas for correcting them (some 
>>>are nitty gritty, and some you already know):
>>>
>>>*) When demand for memory is high, it is possible to run out of 
>>>java.memory before the store has been emptied. Might it be possible to 
>>>make sure the stores are empty before the memory can run out?
>>>
>> 
>> Then we don't need the StoreJanitor, or?
>> 
>> 
>>>*) When memory is low, there is a risk of running out of it before the 
>>>next check. Why not set the interval short enough to ensure there is no 
>>>risk of running out of memory before the next check?
>>>
>> 
>> Be careful with Threads. When they run in a to short interval they'll
>> kill your performance!
>> 
>> 
>>>*) Calling the gc once every check interval seriously undermines system 
>>>performance because it can take several seconds to complete, which is 
>>>comparable to the check interval. Why not call it only when some items 
>>>are released from a store? Why not trust it and use its characteristics 
>>>to advantage?
>>>
>> 
>> That's a contradiction to previous point, I guess. On the one hand you want
>> to increase the the iteration of the Thread on the other hand you want to
>> decrease the GC calls.
>
>
>Ah, but only call the GC if stores are reduced - I think you got it 
>lower down the page.
>
>
>> 
>> 
>>>*) When several instances of Cocoon are running (independent .WAR apps 
>>>in the same servlet container), the calls to gc become very dominant. 
>>>Would this affect the strategy for store-janitor settings?
>>>
>>>*) If the percent to reduce storage is set to 10%, it fails to remove 
>>>any when the number of items are below 10. The number of items to be 
>>>removed needs rounding upwards. Why not remove a fixed number of items 
>>>instead of a percentage? (My idea and now I think it was wrong!!)
>>>
>> 
>> Au, my embarrsing math capabilities strikes agein ;).
>> 
>> 
>>>*) It is difficult to get a good picture of what is happening by 
>>>observing the debug output, so it is difficult to know if it is working 
>>>and difficult use the debug output to optimise choice of janitor 
>>>settings. Might it be possible to make this easy?
>>>
>> 
>> Yes and no. That's always a problem in Cocoon. But you can define your
>> own log target (own file) in the logkit.xconf for the StoreJanitor. Then
>> you get rid of the noise.
>
>
>I suspected something like this might be possible - sounds great!
>
>
>> 
>> 
>>>The proposed, implemented and tested solution to the above works as follows:
>>>
>>>1) Monitor the rate at which memory is consumed during each check 
>>>interval. Remember the biggest rate that has been found so far, to use 
>>>it later. My system logs this at 2.5 megabytes per second.
>>>
>> 
>> Understand.
>> 
>> 
>>>2) If heapIsBig() && freeIsLow(), then attempt to free storage.
>>>
>>>2.1) 'heapIsBig' means that the total memory has exceeded the parameter 
>>>'maxheap'.
>>>
>>>2.2) 'freeIsLow' means the free memory is less than the parameter 'minfree'.
>>>
>>>2.3) Attempt to remove from the stores, the number of items specified by 
>>>the parameter 'reduceby'.
>>>
>>>2.4) To free storage, start at the next store and remove items, moving 
>>>to the next again if necessary, until the specified number of items have 
>>>been removed or all the stores are empty.
>>>
>>>2.5) Then call the garbage collector, but only if some memory items were 
>>>freed.
>>>
>> 
>> Ok, that's nice.
>> 
>> 
>>>3) Sleep for an interval half that in which the memory could run out.
>>>
>>>3.1) If the remaining heap could be more than half filled during the 
>>>interval specified by the 'maxsleep' parameter (at the max rate of 
>>>memory consumption) then sleep for the time it would take to only half 
>>>fill (freememory/maxrate)/2.  Otherwise sleep for the max sleep interval.
>>>
>> 
>> Damn, that's sounds great ;). Your biggest unknown variable is the 
>> "could be". But I think taking the last biggest consumption is not that
>> bad. But how about taking the average of all calls. That would be more exact
>> then the last biggest value.
>
>
>You got straight to the weakest point didn't you? My fear is that a 
>single rogue ridiculously high value might get stuck in there - I think 
>that's possibly what you are getting at.
>
>Can't average all the rates, because you need only the periods where 
>memory is trying to increase as fast as it can. Which ones are these?
>
>Could possibly, average any new highest value with the current highest. 
>Or average two of the current one with the new one (i.e. give a greater 
>weight to the current one).
>
>So, for the moment I've changed it to average the new highest rate with 
>the old - instead of just replacing it. I'm still thinking about this one.
>
> 
>> 
>>>The effect of the store-janitor parameters in cocoon.xconf are now 
>>>slightly changed, so I've changed the names of the parameters to reflect 
>>>this. For the moment the names are changed only inside 
>>>StoreJanitorImpl.java. If the solution were to be adopted then the names 
>>>in cocoon.xconf would also change. The changes, with notes, are as follows:
>>>
>> 
>> Naming was indeed crap.
>> 
>> 
>>>'maxheap' (was 'heapsize')  The maximum total heap size below which 
>>>stores are guaranteed to remain intact.
>>>
>>>'minfree' (was 'freememory') The minimum free heap required for stores 
>>>to remain intact. I have found this should be set to less than 10% of 
>>>avaliable memory, so that the jvm will respond to low memory by 
>>>allocating more heap (if its available), before stores are likely to be 
>>>reduced. Default value might be 2000000. Setting it to zero or very low 
>>>will effectively disable store reduction.
>>>
>>>'maxsleep' (was 'cleanupthreadinterval') The maximum interval between 
>>>checks. Should be short enough to ensure that 'rate of change' data is 
>>>collected before free memory runs low. Suggest 5 secs as default.
>>>
>>>'reduceby' (was 'percent_to_free') is the number of items to be removed 
>>>>>from the stores, on each attempt to reduce the stores. Each  successfull 
>>>attempt to reduce stores results in a call to the garbage collector 
>>>taking several seconds. This limits the rate a which the stores can be 
>>>emptied. Removing several items at a time compensates for this. Using 
>>>the debug output, choose a number of items which results in an increase 
>>>of free memory between successive store reductions. Best tested with a 
>>>sudden high demand for memory when the stores are full. In practice this 
>>>setting is not critical. Suggested default is 10 items. Ideally 
>>>'reduceby' would be in bytes!
>>>
>>>Setting 'minfree' and 'reduceby' both too low can intensify gc activity 
>>>if sudden high demand requires all stores to be completely freed and can 
>>>result in memory running out before all the stores are free. Verify 
>>>using debug output.
>>>
>>>'priority' remains unchanged.
>>>
>>>The above solution is implemented and tested and it works very well 
>>>indeed for me. The parameters do not seem to be at all critical - thank 
>>>goodness! I see no reason why the default settings would need to be 
>>>changed if more memory were available. I have attached the 
>>>StoreJanitorImpl.java so others can test it. I find I can get a very 
>>>good picture of what is happening by using my editor's repeat find 
>>>command on the debug output in the core.log.000001 file. Optimizeit is 
>>>no longer necessary to prove that it works effectively.
>>>
>> 
>> Just define as mentioned above you own log target for the store.janitor.
>> Take a look into logkit.xconf in the WEB-INF dir!
>> 
>> 
>>>Beware! - there might still be things I don't know about that I have not 
>>>take into account.
>>>Ideally - low memory should be detected by some sort of interrupt or 
>>>exception rather than by polling.
>>>
>> 
>> That's correct. But here java is a big white spot.
>> 
>> 
>>>If you are subsequently interested in committing these changes into 
>>>Cocoon and you want me to do some more work to conform to design 
>>>practice etc., then please let me know.
>>>
>> 
>> Yep of course. But I switch to my picky mode now. Please reformat your
>> code to our coding standards.
>> - 4 indents, no tabs.
>> - if(foo)
>>      this.isBad = true;
>> That's not good coding style. Use brackets for each condition or block.
>> - Make it more readable
>
>
>O.K. done that. It now makes a thrilling read! I'm not sure about a 
>sequel though.
>
>
>> 
>> Then I will commit your stuff into the Scratchpad area.
>> (That's the normal way this days)
>> 
>
>
>Peter.
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to