views:

2738

answers:

7
+4  Q: 

JSF Tuning

Running into an issue where JSF is filling up our sessions. We had a system crash the other day. Sent the Heap to IBM for review and found that we had some sessions as large as 50M. They found JSF components in the session and some very large.

So, is there any tuning that can be done? Configuration items to look at? Or other direction.

Our system is build using JSF and Spring for the presentation layer, the back end is EJB, Spring and Hibernate all running on WebSphere 6.1.

A: 

This is the second system I've heard of that has died because of JSF and excessive object creation. The other one also used Spring and Hibernate in the back end. Profiling with OptimizeIt showed that the backend response was on the order of milliseconds for all requests, but you could time the browser rendering again with stopwatch because it took so long - 30 seconds up to several minutes. Memory consumed by the client was ridiculous.

I was only an observer, not a member of that project team. I'll have to ask if the problem was ever fixed and, if so, what the solution might have been.

But if two points make a trend, I'd say that JSF might be fatally flawed. Personally, I stay away from it completely.

Why not try a Spring web front end and see if that helps? If you follow the Spring idiom, it should be a relatively simple matter of replacing JSF with JSTL-based JSPs and Spring controllers.

duffymo
just a personal opinion, but I think the flaw lies with IBM and also their JSF implementation. I cannot justify my feelings :)
The one that I saw fail used the Sun JVM and the Apache JSF implementation. Apache is heavily IBM, so I can't say how the two are different. I think it's the JSF model - it seems very heavy to me.
duffymo
+4  A: 

JSF is a useful technology, but you can certainly hang yourself with it.

It sounds like, either you're inflating the size of the view state (by setting large values on components) or you're leaking references to components into other session state (which would be bad). Another potential culprit would be an excessively large view (I've seen the ease with which people can build UI trees lead to very big control graphs with data tables everywhere). I know that IBM provides rich text and spreadsheet controls - I can't comment on what effect the use of these will have on state size.

The low hanging fruit is to check the managed beans configured for session scope in faces-config.xml.

JSF saves two things between requests:

  • the view (all the controls on the page)
  • the view state (the state of the controls)

These are separated because some controls, such as children of a data table, can have multiple states (one for each row). State can be saved to either a hidden field on the form (which, if unencrypted, can be a big security hazard) or in the session. In order to accommodate multiple browser windows sharing the same session (and, in some implementations, back button support), multiple views are stored.

  • There should be a configuration option to set the number of view states the app will keep in the session for a given user at any given time.
  • You can measure the size of view state by providing a StateManager that measures the size of the saved view/state (configure a StateManager in faces-config.xml with a public constructor that takes a StateManager - see the JSF spec PDFs for more details; the state is serializable and you can check its size by dumping it to a stream).

Most IDE-built JSF apps have backing beans. It would be possible, via session bean scope to hold onto state longer than you want, placing a strain on the session. Since there tends to be one backing bean per page, the more pages you have, the bigger the problem will be. Check your faces-config.xml to see if this is a potential source of problems.

Something else you could do would be to configure a HttpSessionAttributeListener in your web.xml. You can get a stack trace to help identify problem areas in your app.

McDowell
+2  A: 

I was working on a JSF project and found that we had a bug where we were adding multiple JSF h:form elements. Resulting in a copy of the entire viewstate being included with every form. Cutting down to 1 form per page shaved the pages from ~2M down to ~300K.

scurial
+1  A: 

You might be running into issues with lots of backing beans as session scope.

You could try looking into MyFaces Orchestra. This is a library which provides a conversation scope, so once a user has finished with a particular set of beans they will be removed from the session.

I understand that Spring WebFlow has similar features but I haven't really looked into it!

Phill Sacre
A: 

JSF stores the views in session to support it's rich component based architecture (need to maintain its view state) and may fill the heap if not used properly. If you do not have big work flows, always go with small no of views per session. Also avoid keeping backingbeans in session as much as possible. Use custom tag to make the data object just for the next request cycle. We can also use Spring Web Flow with JSF, which introduces view scope and flow scope if we have long workflows in application to reduce the no of views configured in session. JSF can be used for making rich user interface easily, that helps to build Webapplication similar to desktop application. Allot a specific heap to JSF framework to do its work. But use the memory efficiently in the application side and make sure that there is no memory leakage. All memory leaks need to be investigated and corrected during the development itself. Aways use a profiler to find memory leaks and performance bottlenecks that exists in the application.

Mat.

+1  A: 

If you are using MyFaces < 1.1.6 there is a huge memory leak in the way it caches old serialized views in the session effectively never letting them release so that they can be garbage collected. I had a serious problem with that and had 50Mb sessions as well. A quick upgrade of MyFaces rectified the problem without any problems.

A: 

Configure session persistense to database, and it will use least-used algorithm to push least used sessions out of memory. It has high performance (when configured properly) and will help you concretically and fast.