Greetings,
I have rich faces application (3.3.2.SR1). The application uses ModelPanel to view entities. All modal panels are not rendered until I want to show them (rendered = false). Application becomes to be big, and uses a lot relations from one panel to others. All works fine, but it looks like richfaces creates UIComponent tree in memory for all possible cases if component rendred is true or false. When I tried to check memory usage of application (I used YourKit Java Profiler for these needs) I see that it uses a lot of memory for one session.
I am using Facelets together with richfaces and I tried to use
<c:if test="rendred condition"... /> content </c:if>
It starts to use significantly less memory, but...
when I rerender the area with panel, controls on parent screen are stopped to work. I suspect that it is because of every time when component tree is changed it recreates whole tree, and I have unsynchronized client (html) and server (faces) parts.
Could somebody suggest me the way how to reduce memory usage? I have real problem with it as StandardSession object in HeapMemory uses 60-150Mb. And almost all of this memory used for UIControls.
Example of the problem:
I have page which has references to panel1, panel2, panel3.
Panel is:
<rich:modalPanel >
<a4j:outputPanel layout="block"
rendered="#{PanelBeanHolder.renderedViewScreen}">
<ui:insert name="panelContent" />
</a4j:outputPanel>
</rich:modalPanel>
I am rendering panel only when action for this is performed. And do not want to load the UI controls for output panel until I need it.
Thank you in advance.
P.S. I tried to do the following to improve the situation
Configure number of views in session inside web.xml with:
<context-param>
<param-name>com.sun.faces.numberOfViewsInSession</param-name>
<param-value>4</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.numberOfLogicalViews</param-name>
<param-value>4</param-value>
</context-param>
It has to improve StateHolder object, but it doesn't help a lot. I did measuring and memory usage is grows when these number are grow. But, when i tired to set them to 1,1 - some pages stopped work. Sometimes request is forwarded to the welcome page. 2,2 improved the situation, but the issue with forwarding to welcome pages still happens.
Tried to use client mode in javax.faces.STATE_SAVING_METHOD. It still uses a lot of memory for UIComponent model. Even if objects are serialised and have to be stored in the form.
Tried to rewrite stateManager
in faces.config:
<state-manager>org.ajax4jsf.application.CompressAjaxStateManager</state-manager>
and rewrite buildViewState and restoreView for compressing the stream.
It doesn't help a lot.
JSF uses a stateful component tree that is maintained between requests. By default, this is usually maintained in the session. There are features you can use to control this.
Configure state saving parameters
There are usually implementation-specific parameters to control the number of views stored in the session - depending on how your application behaves, this might be an easy win.
You can save the state in forms using the javax.faces.STATE_SAVING_METHOD parameter. However, be aware you're sending more information per request and there are security risks in allowing the client to dictate server-side state (ensure you are happy with how your implementation encrypts this data). You will need to check compatibility with your component libraries (i.e. RichFaces), especially if you're using AJAX.
JSF 2 uses a new state-saving mechanism that reduces the session overhead; your faces-config.xml will need to be updated to the 2.0 version. I believe this idea came from Apache Trinidad, so you may be able to extract a pre-JSF 2 version from there.
Do your own state saving and/or view creation
Implementing your own StateManager and/or ViewHandler lets you take programmatic control over how views are handled. For example, you could write a StateManager that persisted views to a database (with appropriate time-out and clean-up).
Use component binding and transient controls
You can take programmatic control over how components are created. From the spec on binding:
When a component instance is first created (typically by virtue of being referenced by a UIComponentELTag in a JSP page), the JSF implementation will retrieve the ValueExpression for the name binding, and call getValue() on it. If this call returns a non-null UIComponent value (because the JavaBean programmatically instantiated and configured a component already), that instance will be added to the component tree that is being created. If the call returns null, a new component instance will be created, added to the component tree, and setValue() will be called on the ValueExpression (which will cause the property on the JavaBean to be set to the newly created component instance).
When a component tree is recreated during the Restore View phase of the request processing lifecycle, for each component that has a ValueExpression associated with the name “binding”, setValue() will be called on it, passing the recreated component instance.
You could probably use this with the transient property on children to control programmatically control creation/destruction of child components. This is manual and a bit messy, but might work in extreme cases.
I'm sure this isn't an exhaustive list.
Related
I am trying to use portlets based on MVCPortlet on Liferay 6.1.1, and it does not behave as I was expecting. My portlets are supposed to be independent, but are not...
My need:
I have a first portlet A with a form.
I have several instances of a portlet B, based on MVCPortlet.
When the form is submitted, the portlet A launches an event, and all portlet B receive this event. When a portlet B receive the event, it must build an URL, connect to it and read data from it, and display the result.
My B portlet is based on MVCPortlet, is instanceable, ajaxable and with a render-weight of 0, for having a parallel processing and displaying of all instances of portlet B.
But it does not work well:
1) I could not do the processing of the URL in the event processing, as all events reception (one per instance of my portlet B ) are processed in the same thread. So in the event I just set a renderRequest parameter, so the jsp page automatically use an ActionURL to call the action processing in my portlet.
This action builds the URL, use it, process the data, and redirect to the result display page (response.setRenderParameter("jspPage", "/html/display/results.jsp")).
2) I was expecting each portlet to be independent from the other, but they are not. There is only one instance of the MVCPortlet, shared by all portlets, that greatly surprised me. The portlet session is also shared by all my instances of portlet. The action method is executed by different thread, that is good, but the rendering of portlets can be blocked by actions processing of other portlets. One portlet can provoke the whole page refresh. All things that I wanted to avoid by having instanceable, ajaxable and render-weight with 0...
I wonder if there is something wrong, if it is normal to have only one instance of the class extending MVCPortlet, etc. Or if there is a best way to have the desired behavior.
1) I'm not completely sure what you're doing here: Event handling is AFAIK undefined in terms of parallelism, so it's normal behaviour that all events are handled sequentially in the same thread. However, I don't understand what you mean by the ActionURL part of your description. You're able to change state of your portlet in the eventhandler, but not during the render phase. Typically every request handles only one action, multiple (as necessary) events, then renders all portlets. Do you imply that this is followed by an action on every single B-portlet? That's unexpected and I'd rather recommend you do either the processing in your event handler or trigger it to asynchronously run in the back while continuing through the event processing (especially when it takes time)
2) The portlets are independent of each other, however, not every portlet maps to a single Java object. In fact, the implementation is just like in the servlet world: There's only one object that's not supposed to have any state. Almost all instances of member variables in a portlet (or a servlet) are a sign of misunderstanding the API: The whole state of the portlet is coming in through the various PortletRequest and PortletResponse objects, nothing shall be kept within portlet member variables.
Based on your intent to asynchronously render all B portlets, I assume that rendering might take a while - eventhandling should continue as quickly as possible. Otherwise there's no point in rendering asynchronously if the whole result is already there.
I'm currently developing a JSF application with single-page-per-app design, such like in desktop apps. the sections are placed in tabs, and every suboperation, such as editing or inserting item, in displayed in dialog.
What is becoming the issue, it is both the size of ViewState and the processing time of each request. At the moment, the initial size of ViewState in POST is 200kb (and the compression is enabled). The request last from 200 to 400 ms (on my own machine, with no users except me).
Setting state saving to session greatly reduces the request, but greatly increases the processing time - now it's from 350 to 600 ms. Because this is intranet application, net transfer is cheap, so better to send more that process longer.
I don't know how to deal with that problem. Is it possible to reduce the space consumed by JSF components? Most of them don't change on every click, but they seem to be deserialized and processed anyway. Or should I throw out every data (such as dictionaries for drop-down lists) from JSF beans and use intensive caching in service layer? Or there are other options/tricks/improvements I could use?
As you have already figured out, the View State of the entire form is being serialized on every ansynchronous post back so that the server and client can stay in sync. ASP.NET works in pretty much the exact same way.
The Primefaces team has added functionality to many of their Ajax enabled components that allow for Partial Page posts.
http://blog.primefaces.org/?p=1842
The partialSubmit property will only serialize form elements that are specified in the process attribute of the component or <p:ajax>. Of course this is only a solution for Primefaces components, but it has significantly reduced the request size on some of my larger JSF pages.
You can utilize IFrames and session variables to reduce component trees. Each iframe will maintains its own view. Of course in back end process your application is no longer a single page application. However user will still seamlessly see it as a single age applications.
What are the major disadvantages in using a form bean with session scope in struts 1.x?
You need to implement reset() if your form contains attributes populated from checkboxes. You don't need that to request-scoped form beans.
You need to reset the form to its default values if you show a creation form for the second time, else the creation form will redisplay the data coming from the last created/updated object.
You can't have two browser tabs or frames using the same form, because they will walk on each other's toes.
Form beans should be in the request scope by default.
Just try to work with both scopes and choose one preferred for yourself. But I should say there is small difference when you are working with persistent objects (and ORM tools like Hibernate), just because properties are persisted in database between requests.
Infamous checkboxes (and corresponding boolean properties). If you are working with persistent objects (editing boolean properties of some entity), you'll need extra code to reset checkboxes anyways. Scope doesn't matter because boolean property is persistent (isn't cleared automatically between requests).
When you are working with complex persistent objects (hierarchies of objects, mapped by Hibernate onto set of related database tables), often you'll just nest persistent object into form-bean and use nested properties, e.g. <html:text property="purchase.client.name" /> (of course, you can create getters/setters in form-bean for each property of the entire hierarchy, but this is tedious and will complicate further development). For creation you'll just create new empty purchase object in form-bean, for edition you'll load existing purchase from database (request for edit will contain some identifier of object you want to change). Scope doesn't matter again.
About two browser tabs. More important and underestimated problem arises with usage of AJAX requests, especially when they are not idempotent and are overlapped in time (browser issues request for update 1, then request for update 2, while update 1 is still processed on server) - although it is very strange design (I mean overlapping update requests simultaneously in one session from one user). Yes, in that case you'll need to separate data in different requests. But moreover, your action (if we are talking about Struts 1) should be thread-safe, and your business logic should be ready to concurrent/conflicting updates (solve synchronization problems, lock objects, merge/override/reject updates etc.). If you are developing multi-user application, this may happen also when two different users want to change the same object simultaneously. Again, bean scope has little importance comparing to the whole problem.
As you can see, there is only one disadvantage with session-scoped form bean, and it arises only in relation to serious design flaw (overlapping update requests from one user).
Since Wicket automatically manages session state by serializing the components in my page, I'm left wondering, at which level I should attach my state data. More specifically, it seems like a bug I'm having is caused by the WebApplication object being shared among sessions.
Is the application instance shared between sessions?
Should I always attach session data to the Page instance?
What happens if I reuse components with attached session state on multiple pages? Are those instances shared, i.e. if I set the state on the component on one page, is it carried over to another?
I'm guessing, the third bullet point depends on object identity. What does Wicket use to determine that, equals() (like, is it using a Map)?
The data I attached to the application object is state I would need in many pages, so I didn't attach it to the page objects. Is that the correct way to do it in Wicket?
Yes, that's the point of having an Application object. You can store and access application-wide data (usually config) through your Application subclass at any point.
No. There are cases when you need to share session data across multiple pages where storing it in a Session object is more adequate. (An example could be a user login, which definitely belongs to the session and may be used by any page.) Of course you can pass the data around between the pages but it's not a very good strategy. Where the cutoff point is will be your decision: if data is shared between two pages, you might want to pass it from one to the other, if there are 20 pages, you definitely won't want to.
You're not supposed to reuse component instances across different pages. Of course you'll reuse the class but you'll have to construct a new one on each page. This is exactly where storing data in the Session object might come handy.
To clarify: The number of pages sharing state is an indication of where to put the data, but what really matters is how tightly you want the items sharing data to be coupled:
If you pass data as parameters between pages, they will form a tightly coupled group. Depending on what the pages represent, this might be desirable. An example for this may be a wizard-like sequence of pages, with each page knowing what the pages before and after are.
But in the login example we see the opposite: the component populating the login name (probably some kind of login form) must not know about what other components are going to use it. So the logical solution is to store the login name in the session and let each component fetch it as and when they need it.
There are multiple ways to get hold of the current Session object. Check the documentation of the class to see how.
To summarize the information there: Wicket discourages type-unsafe session properties by not providing generic setProperty-like methods. Instead, you are supposed to extend Session, or for most projects, more adequately, WebSession and place typesafe properties in that class. You then override newSession on your application class.
When a screen has multiple interacting Ajax controls and you want to control the visibility of components to react to these controls (so that you only display what makes sense in any given situation), calling target.addComponent() manually on everything you want to update is getting cumbersome and isn't very maintainable.
Eventually the web of onClick and onUpdate callbacks can reach a point where adding a new component to the screen is getting much harder than it's supposed to be.
What are the commonly used strategies (or even libraries if such a thing exists) to avoid this build-up of complexity?
Update: Thank you for your answers, I found all of them very useful, but I can only accept one. Sorry.
In Wicket 1.5 there is an event bus. Each component has onEvent(Object payload) method. With component.send() you can broadcast events and each component can check the payload (e.g. UserJoinedEvent object) and decide whether it wants to participate in the current Ajax response. See http://www.wicket-library.com/wicket-examples/events/ for a simple demo.
You could add structural components such as WebMarkupContainers, when you add this to the AjaxTarget everything contained in it will also get updated. This allows you to update groups of components in a single line.
When I'm creating components for a page I tend to add them to component arrays:
Component[] pageComponents = {
new TextField<String>("Field1"),
new TextField<String>("Field2"),
new TextField<String>("Field3")
}
As of Wicket 1.5 the add functions take array parameters [1]. Therefore elements can be added to the page or target like this:
add(pageComponents);
target.add(pageComponents);
Components can then be grouped based on which you want to refresh together.
[1] http://www.jarvana.com/jarvana/view/org/apache/wicket/wicket/1.5-M3/wicket-1.5-M3-javadoc.jar!/org/apache/wicket/ajax/AjaxRequestTarget.html
Well, of how many components do we speak here? Ten? Twenty? Hundreds?
For up to twenty or about this you can have a state controller which controls which components should be shown. This controller sets the visible field of a components model and you do always add all components to your requests which are handled by the controller. The components ajax events you simply redirect to the controller handle method.
For really large numbers of components which have a too heavy payload for a good performance you could use javascript libraries like jQuery to do the show and hide things by the client.
I currently use some sort of modified Observer-Pattern to simulate an event-bus in Wicket 1.4.
My Pages act as an observable observer since my components don't know each other and are reused in different combinations across multiple pages. Whenever one component receives an Ajax-event that could affect other components as well, it calls a method on it's page with an event-object and the ajax-target. The page calls a similar method on all components which have registered themselves for this kind of event and each component can decide, on the base of the supplied event-object if and how it has to react and can attach itself to the target.
The same can be archived by using the wicket visitor. I don't know which one is better, but I think that's mainly a matter of taste.