| Author |
Message |
|
|
Hi, just want to let you know that there are some issues in the SVN trunk of Icefaces 1. There is a new CliendIdPattern check in getFocusId in the BridgeFacesContext, on some ID strings this matcher takes 5-10 seconds to check the ID.
This is obviously a JVM bug but you might hit this with more clients.
Sample ID which causes problems: mainForm:mainNavPTS:0:usersPTS:0:userEditPTS:0:userEditPTSApplicationSettings:0:xxxTestTree:n-0:settings
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
I changed the getFocusId to the old version as this only seems to be a security check, i couldnt find any negative impact on the app so far.
It seems that this only occures on ice:tree, didnt have any performance problems in other parts of our application, but it looks like it depends on more factors, couldn't quite get the clue. but removing the pattern check helps.
best regards,
daniel
Code:
--- . (revision 24953)
+++ . (working copy)
@@ -378,7 +378,7 @@
public String getFocusId() {
Map map = externalContext.getRequestParameterMap();
String focusedElement = (String) map.get("ice.focus");
- return focusedElement != null && ClientIdPattern.matcher(focusedElement).matches() ? focusedElement : "";
+ return focusedElement != null ? focusedElement : "";
}
|
 |
|
|
oh sorry, i mixed up selectinputtext and selectonelistbox.
i think it's not possible to provide an actinolistener via f:attribute. we solved the problem by calling an empty actionlistener whenever no actionlistener is provided via markup.
<c:if test="#{empty actionBean or empty actionMethod}">
<c:set var="actionBean" value="#{dummyActionBean}"/>
<c:set var="actionMethod" value="dummyActionMethod"/>
</c:set>
(written from memory but you get the concept)
<ice:inputText actionListener="#{actionbean[actinoMethod]}"/>
you always specify the actionListener attribute, it either resolves to an provided method or to the dummyMethod which does nothing.
thats how we solved that problem, not very elegant but it works
|
 |
|
|
Hi
SelectInputText doesn't support ActionListeners per default, you have to implement your own tag and component to do that (subclass the default implementations and provide handling for actionListener)
|
 |
|
|
This means resources are garbaged when the lifetime of a usersession ends?
Cause i couldn't find anything like that in the source, my impression was, that the ResourceDispatcher stuff holds all resources of all sessions in its ArrayLists and there is no point when resources expire. (Except shutdown() method which i thought is called only on applicationcontext shutdown)
Please could clarify to my if and at which time registered resources expire.
If resources expire when a user session expires the problem isn't as severe as we thought it was.
By further investigating our heap dumps we also found a memoryleak in our own code which had a much bigger impact on the memory footprint of our app. I will fix that tomorrow which should alleviate our memory problems a lot.
We will further investigate memory usage when our own leak is fixed and keep you informed.
best regards
daniel
|
 |
|
|
Another sidenote: We use our own Resource Implementation which again holds some references to session objects.
This might be the reason why this leads to problems pretty fast on our servers cause the garbage collector might not be able to destroy expired user sessions as well because of these pointers.
|
 |
|
|
Hi there,
We experienced some performance issues due to full heap memory so i started to profile and take regular heap snapshots and tried tracking down the cause by diffing the results.
Problems start after some days with heavy usage, heap dumps show a _huge_ number of instances of the following classes:
com.icesoft.faces.component.outputresource.RegisteredResource
com.icesoft.faces.webapp.http.core.ResourceDispatcher$ResourceServer$1
com.icesoft.faces.webapp.http.core.ResourceDispatcher$ResourceServer
As a side info: We have a bunch of outputResources in our app which are always visible and change hashcode very frequently.
What i found out is the following: (line numbers refer to current line numbers on HEAD at sventon.icefaces.org)
MainSessionBoundServlet.java:
Code:
77: final ResourceDispatcher resourceDispatcher = new ResourceDispatcher(ResourcePrefix, mimeTypeMatcher, sessionMonitor, configuration);
ResourceDispatcher is created once in the mainsession servlet and passed down through some layers until it reaches...
BridgeFacesContext.java:
Code:
167: this.resourceDispatcher = resourceDispatcher;
... at the constructor and is referenced there. So if i got everything right we just have one Instance of the ResourceDispatcher and every FacesContext holds a reference to it.
OutputResource.java:
Code:
90: path = ((ResourceRegistry) FacesContext.getCurrentInstance()).registerResource(
91: r).getRawPath();
Every OutputResource component registers its resources there.
ResourceDispatcher.java:
Code:
87: registered.add(name);
88: dispatcher.dispatchOn(".*" + name.replaceAll("\\/", "\\/") + dispatchFilename + "$", new ResourceServer(resource));
Every ResourceName gets added to the "registered" ArrayList and the ArrayList only gets cleared in the shutdown() method. (Which is called on context shutdown if i got everything right). Memory Leak 1
PathDispatcherServer.java:
Code:
32: public void dispatchOn(String pathExpression, final Server toServer) {
33: matchers.add(Pattern.compile(pathExpression));
34: servers.add(toServer);
35: }
For every Resource a expression gets added to "matchers" ArrayList, like before the ArrayList ony gets cleared in the shutdown() method. Same applies to "servers" ArrayList. Where servers List is the greate evil because toServer contains a pointer to the resource itself, so the resources also stay in memory. Memory Leak 2
I think this was left undiscovered for a long time as only heavy usage of OuputResources leads to a problem after some uptime of the application server.
We also have a Developer Support Contract, would be nice if this could be fixed asap. Please notify me if we should open a support ticket in addition to that detailed description.
Imho some garbage collection for old resources is needed there and maybe a contextparam to configure resource maximum age.
|
 |
|
|
maybe this thread should go here now, development build feedback is not really what it is anymore.
short summary:
i have 3 paneltabs with one datatable on each, and regardless of which paneltab is the active one, on every request the rendered attribute of all 3 datatables is called. although 2 of them are already invisible because of the paneltab.
old thread:
http://www.icefaces.org/JForum/posts/list/12199.page
|
 |
|
|
just to let you know, this is still the case.
i have 3 paneltabs with one datatable on each, and regardless of which paneltab is the active one, on every request the rendered attribute of all 3 datatables is called.
i don't think this is intended behaviour as this leads to a lot of unnecessary method calls.
|
 |
|
|
facelets has <c:if test=#{expression}>
take a look at the facelets docu.
|
 |
|
|
you can use facelets
<ice:panelTab>
<ui:include src="detail/detail.xhtml"/>
</ice.panelTab>
|
 |
|
|
Hi,
we have kind of performance problems with icefaces in combination with facelets.
we profiled our application and noticed, that some of our getters are called thousands of times. tracing back that situation leaded me to the following:
Facelets passes down all attributes to child tags which are facelets tags too.
To be more precise, we have facelets wrapper tags for almost all icefaces tags we use. <foc:panelTab> <foc:dataTable> <foc:inputText> <foc:outputText> and so on.
We have a <foc:panelTab> which gets rendered="#{bean.method}" and on that tab is a <foc:dataTable> with a lot of <foc:outputText> in it.
Every child of <foc:panelTab> which doesn't have its own rendered attribute evaluates the rendered of the panelTab!
Which leads to a enourmous performance impact. 30k calls of bean.method instead of 1 in our test case.
Anyone noticed this attribute inheritance before? And is there any way around it?
|
 |
|
|
Thanks Mark,
I recalled something the wrong way, the one place where i had to poke around with selectedIndex, i had the problem that they are constant even when rendered="false" and i had to know the index of the first visible tab to select it.
So reconstructing our navigation code with the help of selectedIndex property should be possible with some effort. I will try to do that in a few weeks. Thanks again and sorry for stealin your time :>
rgds daniel
|
 |
|
|
Hmm, i recall that i tried that a long time ago.
I think my problem with selectedIndex was, that it isn't a constant value for a specific panelTab cause rendered attribute on panelTabs shifts their index on the tabSet.
I'll try that one next week.
|
 |
|
|
This is similar to stock JSF 1.2.
Ok, i was just wondering because it was different in IceFaces 1.7.2 and thought it's a sideeffect of the ViewRoot thing.
//
What is curious is the null ViewRoot. What gets rendered in this case?
The same thing that gets rendered when you just reload (F5) a vanilla 1.8 icefaces app in the browser. Everything just like normal, just the componentstate gets reset to default. (first tabpage, first paginatorpage for instance). There is nothing missing or anything like that one would maybe expect with an empty ViewRoot :>
//
Ok, to get into some detail regarding the PhaseListener.
This does some application specific logic.
We send mails to our users which contain links to the application including some get parameters.
The PhaseListener gets the parameters out of the url and depending on that parameters it should navigate to specific tabs on a multilevel tabSet hierarchy. (just forget about that navigationRule, it's just used to remove the getParameters from the url after the tabNavigation is done and has nothing to do with the problem itself)
We used the ViewRoot to find the desired panelTab in the DOM and then set the selectedIndex of all tabSets on the way up (with getParent) to the root again. So that finally on every tabSet the correct panelTab is selected and the desired tab is shown when the output is rendered.
If you imagine a tabset which has another tabset on every tab and each of that tabsets has another tabset on every tab (3 tabSets on the way down). If you want to see a specific tab on the 3rd level the correct tabs on the above tabSets have to be active to actually see the desired tab.
Thats exactly what that phaseListener does, recursively searching for panelTabs and setting selectedIndex of parent tabSets to make that panelTab visible (depending on the getParameters).
This worked like a charm in 1.7 but cause we don't have access to the ViewRoot when the app is called via URL we can't recurse the DOM and can't select the tabs.
I hope this bunch of info did more clarification than confusion.
In fact it can be told in one sentence, we would like to do DOM manipulation in a phaseListener that jumps in when a request is initiated by a url with get parameters. But we don't have access to the DOM cause the ViewRoot is empty.
If you want i can provide you a small testcase on monday.
|
 |
|
|
|
But you can try it yourself, put up a simple app with a panelTabSet, fire it up, change to second panelTab, press browser reload button and you are back in your session but on the first panelTab.
|
 |
|
|