"Philippe Marschall"<[email protected]> wrote:
> >     preallocation OrderedCollection new: instead of relying on its growing 
> > behavior.
>
> Right, but you never know how big the response is going to before
> actually rendering. Otherwise you could just do Array/String new:
> beforehand.

I'm not quite clear about the context here so this may not be relevant, but one 
technique that paid of for us in terms of managing socket buffers was to start 
recycling them. The idea is that if you generally allocate let's say 32K buffer 
for every socket you open, rather then throwing the buffer away when you're 
done with the socket, just put it aside and let the next socket pick up and 
reuse the same instance. For us the main concern was a server being hammered by 
transient connection requests. Occasional buffer allocation could be handled by 
new space scavenger just fine, but a flood of such requests made the buffers 
spill over to the old space and throwing them away got expensive quickly.

Anyway, I realize that your concern is different here, but the same technique 
might help growing in most common cases. If there's a reasonable upper bound on 
most responses (e.g. 32K), you could simply preallocate that size always. If 
the request fits, great, no growing, if not, it will grow. However you'd 
probably have the same sort of problem as we had above if you simply threw each 
buffer away. Recycling should help making it manageable.

We use the same technique in Xtreams, where we need internal buffers quite 
frequently. Check out the RecyclingCenter class there if you want. It's a bit 
more generic because we need to accommodate different collection classes, so 
you'll probably want something different, but the basics should be similar. One 
aspect to note is that the recycling pool can be quite small. You don't need to 
recycle every instance created, you only need to be able to handle the 
"overflow" under load. The idea is that if you are under load and the number of 
concurrently used buffers fluctuates between 100 and 110, you don't need the 
recycling pool size to be 110, but only 10. It only needs to retain the 
temporarily unused buffers long enough for those to get picked up again. When 
the load subsides, it's fine to let the remaining 100 buffers GC, they can be 
allocated again quickly when next wave hits. At the same time it keeps the 
memory load reasonable in the quiet periods.

HTH,

Martin

Reply via email to