[JBoss Seam] - A performance concern with Init.instance(), a suggested work
by raghinii
The short version:
I claim that in Init.instance()
this line:
| Init init = (Init) Contexts.getApplicationContext().get(Init.class);
|
should be replaced with :
| Init init = (Init) Contexts.getApplicationContext().get("org.jboss.seam.core.init")
|
because the current version calles Class.getAnnotation which in turns calls synchronized method and this results in poor behavior under heavy load.
The long version:
First some history (and a similar previous problem):
Over the past few months I've been working with a team converting an existing webapp of moderate complexity to a JSF / Seam stack w/ Facelets.
It's been in production now for about a month and a half.
Running on jboss 4.0.5.GA w/ seam 1.2.0.patch1 Sun JSF RI 1.2 b4 (?)
Before we put it in production had to do some performance tuning. What we started out with was about 10% as fast as the original app , which wasn't acceptable, but eventually we got to about 60%, which was fine.
One undesirable behavior was that under moderately heavy load, when requests were slowing down from their normal ~300ms to 3-4 seconds, the distribution of request response time got very wide with some requests taking 5 seconds while other, identical, requests were timing out at 5 minutes.
With some testing we tracked this down to the fact that org/apache/catalina/core/ApplicationContext.get() is being called something like 50K - 100K times per request in our app. Internally this call is synchronized.
The solution we tried and eventually adopted was to edit the tomcat ApplicationContext code and replace the HashMap with a ConcurrentHashMap and to remove the synchronization in the get().
This resulted in something like a 30-40% performance improvement (if memory serves), but more importantly it significantly narrowed the response time curve. That is, the response time for requests ,under load, was a lot more consistent.
(note 1: this makes sense since having lots of threads contending for a lock can lead to starvation. In this case, the fact that any request has to "win" the lock 100K times before it succeeds makes it more likely that starvation will occur despite any anti-starvation attempts by the OS/VM)
(Note 2: This change not strictly speaking a safe thing to do, but it works for us. (Tomcat 6 also takes this approach but presumably they've gone further in validating that the rest of the app is safe with the concurrent hash map semantics)).
THE CURRENT ISSUE:
Basically, in production under heavy load, we saw the same distribution of request response time. (measured by mod-log-firstbyte in apache). Bascially once the per-page response got to ~7-10 seconds / page some requests start to take 100 - 300 seconds (there's some timeout in the system that caps things at 300 seconds). The situation then often spirals out of control with active connections climbing to the 100s and inevitably resulting in an OOM.
This time a thread-dump of jboss showed that many threads were waiting in to lock a specific lock in java.lang.Class.initAnnotationsIfNecessary().
Looking at the stack traces it became clear that the Class in question was Init.class and that all these threads were calling Init.instance().
( Init.instance() is called ... everywhere... all the time).
The specific line that leads to the eventual lock contention is this one:
Init init = (Init) Contexts.getApplicationContext().get(Init.class);
Which internally leads to a call to get the value of the @Name annotation for the Init.class so that it can then look up the instance by that name.
It is this lookup of the Name of the Init component that causes the contention.
Replacing the get(Init.class) with get("org.jboss.seam.core.init") bypasses this lookup and also that synchronized method.
I've been running this modification on half of the servers for the past two days and they are showing MUCH more linear performance under heavy load. Basically when subjected to a stressor (GC pause, DB related pause, traffic spike etc ) the modified machines return to normal much more quickly (say... 20 -30 seconds compared to 5-10 minutes) and they haven't shown a tendency to spiral out of control towards OOM.
I generally like the compile time checking that one gets from using the get(Class) version of this method, however in this specific case i think the loss of safety is worth it given the deep loop nature of this call.
I'm curious as to what you guys think.
Thanks,
radu
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4042697#4042697
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4042697
17 years, 4 months
[JBoss Seam] - Charset encoding problem in URL parameters
by rmemoria
Hi all,
I've created an inputText field that is passed as a URL parameter like that:
In my page I have
<h:inputText value="#{materialHome.nomeMaterial}" />
| <h:commandButton value="Search" action="/admin/materiais.xhtml" />
And in pages.xml I have
<page view-id="/admin/materiais.xhtml">
| <param name="id" value="#{materialHome.id}" />
| <param name="firstResult" value="#{materiais.firstResult}" />
| <param name="nome" value="#{materialHome.nomeMaterial}" />
| </page>
It works fine, but if I use accents I get problems like this:
If I insert the work balão
After a post I get the inputText with the word balão
I also tried to include in components.xml
<web:character-encoding-filter encoding="UTF-8"
| override-client="true"
| url-pattern="*.seam"/>
with several variations of the encoding param
Any sugestion?
Just for testing, if in pages.xml I remove the line <param name="nome" value="#{materialHome.nomeMaterial}" /> the accents are properly preserved in the inputText.
Thanks,
Ricardo Memória
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4042695#4042695
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4042695
17 years, 4 months
[JBoss Seam] - An enterprise question on s:graphicImage
by gus888
Hi all,
I plan to use s:graphicImage in an enterprise project. I don't know how to save image content source in following two situations:
1) Display a list of small icon images in one page;
2) Click one of them to get a full size image;
Should I save them into two separate image contents (small icon content and full icon content)? Or just save them into one content, then use width=? to display the two situations?
I think if save them into two separate image contents, it will be quicker to retrieve a list of small icon image contents than to retrieve a list of full size image contents from database, but frankly, I don't have any experience on this. I really hope somebody can give me some guidance or advice. I sincerely appreciate it. Thank you very much in advance!
Best regards,
Gus
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4042691#4042691
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4042691
17 years, 4 months
[JBoss Seam] - entity-query.resultCount strange behaviour
by rmemoria
I have a table (Product) with 7000 records and I've configured an entity-query like that:
<framework:entity-query name="products" ejbql="from Product p" max-results="20" order="p.name">
| <framework:restrictions>
| <value>lower(p.name) like lower(#{productHome.productName} + '%')</value>
| </framework:restrictions>
| </framework:entity-query>
In my page I have a resume of the result search (record index and number of records found), pagination control like that in SEAM doc (section 10.3) and an inputText to enter part of the product name like that:
<rich:panel>
| <f:facet name="header">Filtros</f:facet>
| <b>Product name: </b>
| <h:inputText value="#{productHome.productName}" style=" width : 227px;"/>
| <h:commandButton value="Search" />
| </rich:panel>
|
| <p/>
| Results: <b>#{products.firstResult + 1} -
| #{products.firstResult+20 > products.resultCount ? products.resultCount : products.firstResult+20}
| </b> of <b>#{products.resultCount}</b><p/>
|
| <s:link rendered="#{products.previousExists}" value="First page" style="margin-right:20px" >
| <f:param name="firstResult" value="0" />
| <f:param name="name" value="#{productHome.productName}" />
| </s:link>
|
| <s:link rendered="#{products.previousExists}" value="Previous page" style="margin-right:20px" >
| <f:param name="firstResult" value="#{products.previousFirstResult}" />
| <f:param name="name" value="#{Home.productName}" />
| </s:link>
|
| <s:link view="/admin/products.xhtml" rendered="#{products.nextExists}" value="Próxima página" style="margin-right:20px" >
| <f:param name="firstResult" value="#{products.nextFirstResult}" />
| <f:param name="name" value="#{productHome.productName}" />
| </s:link>
|
| <s:link view="/admin/products.xhtml" rendered="#{products.nextExists}" value="Última página" >
| <f:param name="firstResult" value="#{products.lastFirstResult}" />
| <f:param name="name" value="#{productHome.productName}" />
| </s:link>
and the rest of the page is a dataTable that is working perfectly.
The code in bold shows a resume like in google:
Result: 1-20 of 7500 (for example)
In pages.xml I have:
<page view-id="/admin/products.xhtml">
| <param name="firstResult" value="#{products.firstResult}" />
| <param name="name" value="#{productHome.productName}" />
| <navigation from-action="#{productHome.remove}">
| <redirect view-id="/admin/products.xhtml"></redirect>
| </navigation>
| </page>
If I inform part of a product name, the datatable shows the products filtered correctly, but the property products.resultCount returns the total number of records (without filtering)
Detail: If I filter again (the same filter) or move to the next page using the navigation controls, the resultCount returns the right number (filtered).
I don't know if I made something wrong or it's a bug.
Any sugestion or workaround to this problem.
Thanks,
Ricardo Memória
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4042688#4042688
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4042688
17 years, 4 months