Simon Kitching schrieb:
Daniel Niklas schrieb:
Hi,
i am using server-side state saving (because the environment is a
portal). I
noticed a high memory consumption for the view state, or exacting for
the
history of old view states. Now i have some questions on this:
1)
Is view state history *only* for "back-Button" of the browser?
It is also needed to support multiple windows for the same webapp.
Actually, this doesn't really work properly but having some old view
states at least makes it work some of the time.
The idea is that by setting NUMBER_OF_VIEWS_IN_SESSION, a webapp can
guarantee to support a certain number of back-button clicks - at the
JSF level at least.
Or that when two windows are open on the same webapp, that the user
can perform NUMBER_OF_VIEWS_IN_SESSION clicks in one window before the
other window starts to misbehave.
In practice, neither of these are very useful if the application uses
session-scoped beans of any type as these are not "versioned" like the
view, and so trying to go "back" to a previous view (or use a separate
window) while having just one copy of the session-scoped beans is
usually a problem. An app needs to use only request-scoped beans, or
Orchestra conversation-scoped beans for this to function correctly.
The "weak" map stuff then tries to make life nice for the user; when
there is memory to spare then it tries to keep as many old views as
possible, so that even more than NUMBER_OF_VIEWS_IN_SESSION clicks
will work. But when memory is low, only NUMBER_OF_VIEWS_IN_SESSION
clicks are guaranteed to work.
2)
There is a (Weak/Soft) ReferenceMap for old view states. Theses
instances
comes into old generation memory. I think, the garbage collector must
often
clean up these objects. Is this an optimal behavior?
I'm using myfaces 1.1.5. Here the old views are hold with soft
references.
Is this working? I found an issue
https://issues.apache.org/jira/browse/MYFACES-1658.
In 1.1.6 the ReferenceMap holds only weak values and keys. Why that?
I'm not sure what you're asking here. Why do you think that something
is not working?
The original code used the default constructor for ReferenceMap, which
uses strong refs to keys but weak refs to values. The key object here
is not large; it is the value (which is the whole UIViewRoot) that is
held weakly. However nothing *ever* clears the keys for this map. So
as the profiling tests referenced in the original email thread show,
there is a leak: when a single user makes a large number of requests
in the same session then eventually the number of key objects in the
map builds up to unreasonably large number. They are small, but enough
of them add up.
The fix was to use weak refs for the keys as well. And the profiling
tests showed that this solved the issue.
I suspect that there is a *slight* leak here. Suppose a user performs
a lot of requests, then stops. The garbage-collector will eventually
reclaim both the key and value objects from the "old" map. But it
won't reclaim the Map.Entry objects used by the ReferenceMap itself. I
presume that these get collected when any method is called on
ReferenceMap, but as the user is inactive that doesn't happen. So some
memory is held by the user until the session expires. Probably not a
problem in practice though.
Is that what you wanted to know?
Hmm..actually, should this map be using SoftReference rather than
WeakReference?
The garbage-collector should collect a WeakReference as soon as it can.
So this cache will almost always be empty. The garbage-collector will
collect a SoftReference only when memory is low. That seems more
appropriate for this kind of cache.
Regards,
Simon