Yep, good question. I'm interested in the answer to this one. Also has anyone looked at whether the session size makes Seam an easy target for a denial of service attack.
Any thoughts Seam Team ??
post your code for analysis, this is an interesting subject that is not covered in any of the Seam books thus far.
EntityManagers cache all objects loaded into them. If you have a session scoped entityManager it will contain a reference to every entity that has been loaded in the users session.
I used the JProfiler to analyze the used memory and was surprised how much memory is used by the seam application. I ran a stress test and after some minutes the heap space was gone. With just 20 Sessions the heap space of 1GB was eaten up and I received and out of memory exception.
Is there any good pratice to reduce the amount of memory used by a SEAM application especially in combination with JSF?
I checked seam booking application (booking page) and the session size reaches nearly 30 MB.
I think only the conversational pages seams to have this spike. The intial seam pages looks fine.
FYI, I am using Seam 2.0 GA with Jboss EAP 4.2.
Anything you stick in the conversation ends up in the HTTPSession, including all the entities loaded into a conversation scoped EntityManager.
SFSB's are good here, because the container can passivate them to conserve resources if need be.
The problem is: We don't even use conversational scoped elements. The main part consists of event and page scoped elements and we use JBoss 4.2.2, Richfaces 3.2.2 and SEAM 2.0.1.SP1. The average sessions size grows about 10MB and we can't find a way to reduce it.
Page scoped elements eh? I have never used these in my application, but thinking about it they would probably not have the same well defined lifestyle as a conversation scoped element. If a use navigates away from a page without submitting a faces request (i.e. s:link or s:button) the app has not way of knowing this, and would have to keep those page scoped components lying around until the page exprires. Could this be the problem?
If so, there are only two (maybee three) ways around it:
1) Use conversation scoped elements and start the conversation when you enter the page and end the conversation when you leave it.
2) make sure you are using h:commandLink and h:commandButton instead of s:link and s:button.
3) (not sure about this one) Use a seam remoting call in the unload event of your pages to destroy the page context. No idea how you would do this.
I'm also mainly using PAGE scope and find this a very interesting topic.
I'm curious about the tools you are using for estimating the heap size since I would like to do some checking of our application.
Also regarding page scope the reference docs say it is
serialized to the client, I thought that meant that it wouldn't be kept around in the session. Not sure what this means though, I kind of assumed that it works like the a4j:keepAlive and t:saveState components. Would be great with a clarification to remove any certainty :)
I've got similar concerns. It's to the point where I'm not sure if Seam is production ready for very large apps. (Note, not sure what other people consider
largebut to me it's something w/ a code base consisting of 50 plus entities, 1.4 views per entity, and 500 plus user base - right now my app has 2 of those 3 requirements).
I did find a few things, partially based on posts here, and partially based on my own discoveries. Note that I have at a latest confirmed these in 2.1.1CR2, but it's only my opinion as I'd say these are causes of
too much memory.
- The EntityHome class is designed in a way to be useful only if you're editing entities directly, one at a time. Other uses seem to use a bit of memory. Right now I use app scoped SLSBs but am considering changing them to POJOs.
- You can't use Extended persistence context. It just eats way too much memory. It seems that using an injected EM is the preferred way as of 2.1, can't say I agree (even though it's currently what I'm using).
- Reduce FK relationships on lazy fetched entities. I've noticed that seam seems to load them randomly. I do this by writing queries that return sets of entities that match a given parent entity.
- Avoid using seam via java script directly. This seems to cause large spikes. If you can, just rely on how your view layer handles it.
- This one might just be with how my app's written, but use your own queries whenever possible.
I think it depends on if you are using server side or client side state saving, it looks like it is stored in the ViewRoot's attributeMap.
Are the people that are having problems with session size using client or server side state saving?
could you be more specific? what are the alternatives to storing it in the ViewRoot. How do we determine, if we're running on a seam-gen'd app.