论坛

主页 » Liferay Portal » English » 3. Development

组合视图 统一视图 树状图
讨论主题 [ 上一个 | 下一个 ]
toggle
Paul Butenko
Vaadin portlet memory leak on handleRenderRequest
2013年4月18日 上午4:26
答复

Paul Butenko

等级: Junior Member

帖子: 38

加入日期: 2010年7月1日

最近的帖子

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
附件

附件: heap-dump.png (66.8k)
David H Nebinger
RE: Vaadin portlet memory leak on handleRenderRequest
2013年4月18日 上午5:46
答复

David H Nebinger

Community Moderator

等级: Liferay Legend

帖子: 11112

加入日期: 2006年9月1日

最近的帖子

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
2013年4月18日 上午6:33
答复

Paul Butenko

等级: Junior Member

帖子: 38

加入日期: 2010年7月1日

最近的帖子

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
2013年4月18日 上午7:11
答复

David H Nebinger

Community Moderator

等级: Liferay Legend

帖子: 11112

加入日期: 2006年9月1日

最近的帖子

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
2013年4月18日 上午7:15
答复

David H Nebinger

Community Moderator

等级: Liferay Legend

帖子: 11112

加入日期: 2006年9月1日

最近的帖子

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
2013年4月18日 上午10:53
答复

Jack Bakker

等级: Liferay Master

帖子: 840

加入日期: 2010年1月3日

最近的帖子

for some use cases ?restartApplication can be added to url to refresh state to default
Paul Butenko
RE: Vaadin portlet memory leak on handleRenderRequest
2013年4月21日 下午11:07
答复

Paul Butenko

等级: Junior Member

帖子: 38

加入日期: 2010年7月1日

最近的帖子

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
2013年4月21日 下午11:09
答复

Paul Butenko

等级: Junior Member

帖子: 38

加入日期: 2010年7月1日

最近的帖子

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
2013年4月21日 下午11:10
答复

Paul Butenko

等级: Junior Member

帖子: 38

加入日期: 2010年7月1日

最近的帖子

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