Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Paul Butenko
Vaadin portlet memory leak on handleRenderRequest
April 18, 2013 4:26 AM
Answer

Paul Butenko

Rank: Junior Member

Posts: 38

Join Date: July 1, 2010

Recent Posts

Hi,
I have made some test with Vaadin portlet which can be reinitialized on handleRenderRequest and faced some strange problem.
Here is code of the portlet:

 1
 2public class Vaadin_load_portletApplication extends Application {
 3  Window mainWindow;
 4
 5  @Override
 6  public void init() {
 7    mainWindow = new Window("Vaadin_load_portlet Application");
 8    Label label = new Label("Hello Vaadin user");
 9    mainWindow.addComponent(label);
10
11    // set portlet listener, check if application is portlet and init user with listener
12    if (getContext() instanceof PortletApplicationContext2) {
13      PortletApplicationContext2 ctx = (PortletApplicationContext2) getContext();
14      ctx.addPortletListener(this, new CustomListener());
15    } else {
16      getMainWindow().showNotification("Not inited via Portal!", Notification.TYPE_ERROR_MESSAGE);
17    }
18
19    setMainWindow(mainWindow);
20  }
21
22  private class CustomListener implements PortletListener {
23
24    /** The Constant serialVersionUID. */
25    private static final long serialVersionUID = -6973370282667721257L;
26
27    /** {@inheritDoc}  */
28    public void handleRenderRequest(final RenderRequest request,
29                                    final RenderResponse response,
30                                    final Window window) {
31      synchronized (this) {
32        if (PortletMode.VIEW.equals(request.getPortletMode())) {
33
34          mainWindow.removeAllComponents();
35          System.out.println("removed all components");
36
37          mainWindow.addComponent(new Label("test"));
38          System.out.println("added label");
39
40        }
41      }
42    }
43
44    /** {@inheritDoc}  */
45
46    public void handleActionRequest(final ActionRequest request,
47                                    final ActionResponse response,
48                                    final Window window) {}
49
50    /** {@inheritDoc}  */
51
52    public void handleEventRequest(final EventRequest request,
53                                   final EventResponse response,
54                                   final Window window) {}
55
56    /** {@inheritDoc}  */
57
58    public void handleResourceRequest(final ResourceRequest request,
59                                      final ResourceResponse response,
60                                      final Window window) {
61
62    }
63  }
64}



As you can see it is pretty simple, on each render request all component from mainWindow removed and new label text added.

I performed some load test of this portlet, which simply open page with portlet 4000 times (100 users with 40 repeated requests)

At the end of test I have analyzed heap dump I faced that instances of Label object is not collected with GC. I think this is not good since in case of lomg term portlet usage out of memory exception will be thrown.

I'm using vaadin 6.7.4 and liferay 6.1.1.

How this can be avoided?

Thanks in advance,
Paul Butenko
Attachment

Attachments: heap-dump.png (66.8k)
David H Nebinger
RE: Vaadin portlet memory leak on handleRenderRequest
April 18, 2013 5:46 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 7252

Join Date: September 1, 2006

Recent Posts

The default version shipped with Liferay is pretty old, you should have the Vaadin control panel, upgrade Vaadin to 6.8.10, recompile the widgetset, and try again.

Honestly, though, this does not represent what I'd code in a Vaadin application. In the init() method you instantiate your objects (even the ones that are not added). In the mode switch code, you swap between the existing components rather than instantiating new ones.

Creating new objects on the fly is just not practical.
Paul Butenko
RE: Vaadin portlet memory leak on handleRenderRequest
April 18, 2013 6:33 AM
Answer

Paul Butenko

Rank: Junior Member

Posts: 38

Join Date: July 1, 2010

Recent Posts

Yes, I agree, it is not practical.
But if application should totally refresh its state to default. Think, it is easier to create new instance of the view then fully refresh each component to initial state, especially if application has lot of it.

Will try to upgrade vaadin.jar.

Thank you for help.
David H Nebinger
RE: Vaadin portlet memory leak on handleRenderRequest
April 18, 2013 7:11 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 7252

Join Date: September 1, 2006

Recent Posts

Each decision to take an easy road comes with side effects...

The problem I believe is that even though all components were removed, that doesn't mean they are not pointed at by some other piece of Vaadin code so they're not candidates for GC.
David H Nebinger
RE: Vaadin portlet memory leak on handleRenderRequest
April 18, 2013 7:15 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 7252

Join Date: September 1, 2006

Recent Posts

I've been doing work with V7 in the portal using the new Navigator/View concept. All of this does not come into play in V6, but basically when a view is activated, the view's enter() method is invoked. I think the basic intent is that this enter() method should reset the component to default values. I tend to use lazy initialization, so in my enter() methods I will create components if they haven't already been created (just doing constructor and setter calls and add to the view), then fall into my 'reset' code.

While I'm glad to see you using Vaadin and glad to help you become successful, there are some oddities such as this that you'll have to be wary of...
Jack Bakker
RE: Vaadin portlet memory leak on handleRenderRequest
April 18, 2013 10:53 AM
Answer

Jack Bakker

Rank: Liferay Master

Posts: 646

Join Date: January 3, 2010

Recent Posts

for some use cases ?restartApplication can be added to url to refresh state to default
Paul Butenko
RE: Vaadin portlet memory leak on handleRenderRequest
April 21, 2013 11:07 PM
Answer

Paul Butenko

Rank: Junior Member

Posts: 38

Join Date: July 1, 2010

Recent Posts

Jack Bakker:
for some use cases ?restartApplication can be added to url to refresh state to default



Yes, In dev env it is Ok, but not in production.
Paul Butenko
RE: Vaadin portlet memory leak on handleRenderRequest
April 21, 2013 11:09 PM
Answer

Paul Butenko

Rank: Junior Member

Posts: 38

Join Date: July 1, 2010

Recent Posts

In my main application I did some reset method for all componentes and it solved problem with memory leak, but still I didn't found the reason why creating and attaching new component to main window does this memory leak.

Thnks for help.
Paul Butenko
RE: Vaadin portlet memory leak on handleRenderRequest
April 21, 2013 11:10 PM
Answer

Paul Butenko

Rank: Junior Member

Posts: 38

Join Date: July 1, 2010

Recent Posts

Vaadin upgrade didn't helped.
Also I created new thread at vaadin forum - https://vaadin.com/forum#!/thread/3015168