Alexander Klimetschek skrev:
Daniel Fagerstrom schrieb:
One possibility is that there is some fault in the component handling
so that the block servlet component or tree processor is recreated
instead of reused in some cases.
This seems to be the real problem. There are new ResourceReader
instances for each request (along with the BlockSource,
BlockConnection etc. connected with it), but they are never reused.
Instead they keep in memory, referenced by some ThreadLocal storage.
Something in the special handling o.a.c.sitemap.SitemapServlet might
be buggy, but we cannot see what. Do you have time to further look at
that this week? When using forms, the amount of data that is collected
this way increases so fast, that we sometimes get an OutOfMemory after
3-4 reloads...
I have not done any tests yet but have looked at the code.
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?
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.
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.
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.
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.
Also it would be worthwhile to scrutinize that all streams are closed as
they should.
/Daniel