On 10/26/05, Fernando Padilla <[EMAIL PROTECTED]> wrote:
> A few weeks ago we had a memory leak that we thought was caused by
> Tapestry, but was in fact caused by us confusing Tapestry.  We had gone
> and overriden the getLocale() method in the BasePage to return a "new
> Locale( "en_US" )" which totally confused Tapestry's PagePool, so that
> it never recognized the PagePool key and recompiled every page on every
> request.. we discovered this after we had it in production.. arg.  We
> simply replaced it to return "Locale.US", and it was fine.
>

Interesting; perhaps we should key on the Locale's toString() to avoid
this problem?

>
>
> I've been meaning to write to the list what I've learned, so it looks
> like this is a good a time as any.  So this is how I see it.  Could
> someone check my logic?
>
> (I've been using Tap 4)
>
> -- GeneratedMethodAccessor --
>
> Because of Java VM issues, every time there is some Classloader/Bytecode
> magic it creates an object that can not be garbage collected.  This will
> supposedly be fixed in the next version of java. (** I read this on an
> online blog after I googled for "GeneratedMethodAccessor", the only
> thing useful that I found. **)
>
> Thus the number of pages compiled by Tapestry has a permanent impact on
> the memory footprint of the application.
>

In production, the number of so generated classes is entirely finite.

>
> -- PagePool --
>
> Tapestry keeps a cache of compiled pages in it's PagePool so that it can
> reuse compiled pages.  It does this with a unique key of "pagename and
> locale".  The PagePool implementation compiles a new page if there
> aren't any in the pool.
>
> If you have 100 concurrent requests for the same page, then it will
> compile 100 copies of the page.  If you then have 100 concurrent
> requests for the same page, but with a different Locale, it will compile
> another 100 copies.

>
>
> -- PagePool lacking --
>
> It seems like the number of pages compiled by Tapestry has a permanent
> impact on the memory footprint for another reason.  It seems like
> Tapestry's PagePool does not release "idle" pages. (** This is only what
> it looks like through profiler, haven't confirmed in code; anyone want
> to confirm? **)  Thus the PagePool will grow in order to handle an flash
> flood of concurrent requests, but will not release those pages after the
> abnormal load dissipates.
>


I decided to leave the page pool mechanics very simple, since it is so
easy for the underlying HiveMind service to be overridden with
something smarter. A complete solution would purge out unused page
instances after some period of time (Tapestry 3 did this, but the
thread it spawned to act as a janitor caused lots of problems).


>
> -- PagePool enhancement --
>
> Anyhow, maybe one of us using Tapestry for high profile production
> systems should take some time to make a better PagePool implementation:
> - more tuning parameters
> - release of unused/idle pages
> - limit the unbounded compile of pages based on concurrent requests
>   - maybe have a slow growth pattern with blocking, limiting the
>     concurrent request handling on flash mobs, but avoiding the real
>     possibility of out of memory situations..
>
>

I think an ideal page pool would properly track how many of each page
has been allocated and set an upper limit on the number of page
instances; would block for a short period of time, waiting for a page
instance to become available, and would eventually fail with some kind
of "application busy" message.

Suddenly, the API for ObjectPool and PageSource gets a bit more
complicated to handle these cases.  In a desperate situation, how do
you handle rendering an exception page if now exception page instances
are available?  I guess that, eventually, you send an HTTP 500
response.


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

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

Reply via email to