cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexander Klimetschek <>
Subject Re: Performance with blocks protocol
Date Tue, 07 Nov 2006 22:28:02 GMT
Daniel Fagerstrom schrieb:
> First The BlockServlets are configured to be singletons and created by 
> the Spring container. A BlockServlet in turn creates a SitemapServlet 
> (or whatever servlet type it is configured to create) in its init 
> method. The Sitemap servlet creates a TreeProcessor in its init method. 
> The DispatcherServlet connects to the BlockServlets in its init method. 
> All components mentioned this far should AFAICS be singletons. Does this 
> hold in practice in your tests?

Yes. The exact numbers are (we have n=7 blocks), after 2 reloads of a 
static page with a number of resources (images, css):

- 1 DispatcherServlet
- 7 BlockServlet
- 7 SitemapServlet

- 8 (n+1) TreeProcessor
- 8 (n+1) EnvironmentHelper

- 24 BlockCallHttpServletRequest

- 27 ReadNode

- 67 ResourceReader

- 69 HttpEnvironment
- 69 HttpRequest
- 69 HttpResponse
- 69 NonCachingProcessingPipeline

> The TreeProcessor is a singleton but it gets and populates a new 
> pipeline at each request, so new ResourceReaders are supposed to be 
> created. Sources are factory based so a new BlockSource is created and 
> it creates in turn a new BlockConnection. All this is expected, so the 
> question is if they are destroyed correctly.

It very much looks like they are not destroyed.

> Looking at the ResourceReader it is Recyclable and has a default 
> max-pool-size of 32. I don't know enough about the Avalon life style 
> implementation to know exactly what happens. As long as there are no 
> more than 32 instances of ResourceReaders they are, AFAIU supposed to be 
> kept in a pool in the memory. But we would get a problem if the recycle 
> method of the ResourceReader is called to late or not at all in that 
> case the other object would be kept in memory when they should have been 
> garbage collected.

There is no config, so the default value of 32 is used, but as listed 
above, there are actually more than 32 instances.

> The BlockCallStack contains stacks in thread local memory that contain 
> BlockContexts. AFAICS they don't have any references to things that 
> should be garbage collected, but if they do we would have a problem.

I will look into that now.

> Looking in the RequestProcessor that is called by the standard 
> SitemapServlet, it calls ProcessingUtil.cleanup(), while leaving the 
> processing of a request. I don't call that in the corresponding code in 
> the o.a.c.sitemap.SitemapServlet, that might be a problem.

I have copied that, because I tried to figure out what is different 
between the sitemap.SitemapServlet and the RequestProcessor, but it did 
not change anything with the memory leak.

> Also it would be worthwhile to scrutinize that all streams are closed as 
> they should.

I also implemented the flush() and close() methods in 
BlockCallHttpServletResponse.getOutputStream() (in that anonymous inner 
class), passing on the stuff to the internal stream, where flush() quite 
often gets called, but close() not. Then I saw that there "should" be a 
close() call in BlockConnection.getInputStream() and I added a 
"os.close();" right before "return new ByteArrayInputStream(out);".


Alexander Klimetschek

View raw message