You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Leonardo Uribe <lu...@gmail.com> on 2012/12/17 17:23:50 UTC

[core][proposal] JSF View Pooling (going beyond JSF Stateless Mode)

Hi

In the last months, I have been doing some investigations around
"stateless JSF" ideas. The intention is try to find ways to improve
MyFaces Core performance as much as possible, without lose all those
nice features we all are used to.

In summary, the justification around stateless JSF is that, if it is
possible to cut the build view time from a request, there will be an
improvement from both speed and memory perspective. This is true, but
only to some point, because the response time for a request is given
by the build view, validation/invoke application and render response
time.

To get to the same goal, without sacrifice JSF stateful behavior,
other improvements has been already done (cache EL expressions, cache
ids, make tree structure lighter, ...). The idea is cache that
"stateless information" into a place where it can be reused
effectively, which in this case is inside Facelet abstract syntax tree
(AST). This has worked well so far. The side effects of enable these
optimizations has been analysed, and there is a good understanding
about this.

In few words, the basic idea about stateless JSF as proposed
originally by Rudi Simic in his blog is this:

Mark the view as stateless using some attribute.
Use a pool of views, because views are not thread safe.
Before store the view in the pool, use a visitTree call to reset the fields.

Unfortunately, it was quickly found that the implementation proposed
requires a better view pool and try to reset the fields is not
fail-safe, because the component tree also stores more than just the
input field values. Additionally, it doesn't provide a way to use it
for dynamic views.

Provide a thread safe implementation of UIComponent that can be reused
across threads is not a  good solution, because anyway there is some
information that is inside UIComponent and should be stored per
thread, and precisely UIComponent is a place specifically designed to
store that information.

Based on the previous background, the big question is if a solution
based on object pooling pattern can be done effectively for a web
framework like JSF. A good description of the technique and its
trade-off can be found at:

http://en.wikipedia.org/wiki/Object_pool_pattern

In few words, the proposal is go "Beyond JSF Stateless Mode", and
instead blame the state, make it your friend. Let's just take
advantage of the stateful nature of JSF to allow reuse views fully or
partially.

How?

- PSS algorithm can be used to check if a view has been modified or
not, checking its state. So, it can be used to check which components
has state, and if it is possible to provide a way to reset the state
of a component to the initial state set by the first
markInitialState(), restore the state is possible.

- If the view cannot be reset fully, it is possible to use facelets
refreshing algorithm and reuse a view partially.

- Add some additional code to recover a view instance when it is
discarded, and store it into the view pool. This requires some changes
over NavigationHandlerImpl, because it is not possible to reuse a view
and store it in the pool that is still on usage, so it is necessary to
do a "deferred navigation", changing the default ActionListenerImpl
and ensure handleNavigation() is called before end invoke application
phase but outside the visitTree() call.

- In MyFaces there exists the concept of FaceletState. It is possible
to use this concept and cache even dynamic views, because each
different FaceletState can identify an specific view structure.

I have created this issue:

https://issues.apache.org/jira/browse/MYFACES-3664

The intention of this mail is get some feedback from the community
about this topic. I have a working prototype, so the intention is
create a branch for this topic at the end of January and
commit/release this feature for MyFaces Core 2.1.x branch at the end
of March, just for CONFESS 2013 conference (See
https://2013.con-fess.com/ ).

If you have a good idea, doubt, observation or just you want to say
something about this topic, it is a good moment to do it. There is a
lot of details involved that needs to be defined, so the intention is
discuss them and see how they should looks like.

regards,

Leonardo Uribe

Re: [core][proposal] JSF View Pooling (going beyond JSF Stateless Mode)

Posted by Leonardo Uribe <lu...@gmail.com>.
Hi Martin

2012/12/20 Martin Marinschek <mm...@apache.org>:
> Hi Leo.
>
> what are you trying to gain from this?
>
> Here the criticism from the link you provided:
>
> Criticism
>
> Some publications do not recommend using object pooling with certain
> languages, such as Java, especially for objects that only use memory and
> hold no external resources.[2] Opponents usually say that object allocation
> is relatively fast in modern languages with garbage collectors; while the
> operator new needs only ten instructions, the classic new - delete pair
> found in pooling designs requires hundreds of them as it does more complex
> work. Also, most garbage collectors scan "live" object references, and not
> the memory that these objects use for their content. This means that any
> number of "dead" objects without references can be discarded with little
> cost. In contrast, keeping a large number of "live" but unused objects
> increases the duration of garbage collection.[1] In some cases, programs
> that use garbage collection instead of directly managing memory may run
> faster.
>
>
> what do you say about this?

To avoid the effect over garbage collection, the view pool proposed uses
soft or weak references to hold UIViewRoot instances and to avoid lower
performance by concurrency effect, the pool does not have any
synchronized block it uses a ConcurrentLinkedQueue with a upper
limit set by an atomic var (just one synch block and the performance
will be lower than do not using anything at all).

The effect of use soft/weak references is that the region of memory holding
the instance can be always reclaimed by the garbage collector, avoiding
memory fragmentation.

>From memory perspective, the cache improves memory usage because
less object needs to be created per request, so the pressure over gc
becomes many times lower, and at the end we have less calls for gc
and a better performance at the cost of have a higher memory footprint.

In MyFaces case, we have done the best effort to keep component tree
"as light as possible", which means create the less amount of objects
per component. This makes view creation very fast, but anyway, the
amount of objects that still needs to be created per view are enough to
consider object pooling technique.

The tests done under high concurrency (200 threads) shows an
improvement of about 8% rendering full pages. The reason is the build
view time for our facelets algorithm is already very fast, and render
the view is the operation that takes more time. But in ajax cases
the improvement is even more, because in that case, usually the portion
that needs to be rendered from the view is small, and the build view
time becomes more significant. The difference will be more significant
if the view is larger.

Is the technique good enough to be included in MyFaces? In my
opinion yes, because given the considerations done there is a gain even
in the most simple cases. But not everything is perfect. The technique
suppose PostAddToViewEvent will not be called in each request, if you
use c:set, ui:param or something that makes ValueExpressions depends
on VariableResolver and in that way make necessary to create them
at each request, the view becomes non poolable, and it also requires
some small modifications over components to allow reset the component.

In any case, the proposed patch will help to clear the misunderstandings
about stateful vs stateless web frameworks and the implications in
performance.

best regards,

Leonardo

>
> best regards,
>
> Martin
>
>
> On Mon, Dec 17, 2012 at 5:23 PM, Leonardo Uribe <lu...@gmail.com> wrote:
>>
>> recover
>
>
>
>
> --
>
> http://www.irian.at
>
> Your JSF powerhouse -
> JSF Consulting, Development and
> Courses in English and German
>
> Professional Support for Apache MyFaces

Re: [core][proposal] JSF View Pooling (going beyond JSF Stateless Mode)

Posted by Martin Marinschek <mm...@apache.org>.
Hi Leo.

what are you trying to gain from this?

Here the criticism from the link you provided:

Criticism

Some publications do not recommend using object pooling with certain
languages, such as Java, especially for objects that only use memory and
hold no external
resources.[2]<http://en.wikipedia.org/wiki/Object_pool_pattern#cite_note-2>Opponents
usually say that object allocation is relatively fast in modern
languages with garbage
collectors<http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29>;
while the operator new needs only ten instructions, the classic new -
deletepair found in pooling designs requires hundreds of them as it
does more
complex work. Also, most garbage collectors scan "live" object references,
and not the memory that these objects use for their content. This means
that any number of "dead" objects without references can be discarded with
little cost. In contrast, keeping a large number of "live" but unused
objects increases the duration of garbage
collection.[1]<http://en.wikipedia.org/wiki/Object_pool_pattern#cite_note-urban-1>In
some cases, programs that use garbage collection instead of directly
managing memory may run faster.


what do you say about this?

best regards,

Martin

On Mon, Dec 17, 2012 at 5:23 PM, Leonardo Uribe <lu...@gmail.com> wrote:

> recover




-- 

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces