Bug 399523 - Memory/SWT leak in JpaDetailsView
Summary: Memory/SWT leak in JpaDetailsView
Status: RESOLVED FIXED
Alias: None
Product: Dali JPA Tools
Classification: WebTools
Component: JPA (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.3   Edit
Assignee: Brian Vosburgh CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2013-01-30 12:59 EST by Snjezana Peco CLA
Modified: 2014-07-01 02:38 EDT (History)
3 users (show)

See Also:


Attachments
A patch (1.46 KB, patch)
2013-01-30 13:02 EST, Snjezana Peco CLA
no flags Details | Diff
Sample project to reproduce the issue (5.38 KB, application/x-zip-compressed)
2014-07-01 02:37 EDT, wei cai CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Snjezana Peco CLA 2013-01-30 12:59:42 EST
Steps to reproduce:

1) create a JPA project
2) add several entities
3) open the JPA perspective
4) open some entity
5) select the entity and its properties
6) rebuild the project

Repeat the steps 4-6. After a while, depending on the size of the project and the JVM heap size, you will get either an OOM exception or "no more handles" SWT error.
You can also see that every project rebuilding leaks thousands JPA objects.

The issue comes because, for an individual type of JPA node, JpaDetailsView remembers the JpaDetailsPageManager objects in the pageManagers hash map. 
The key is an object of the type JpaStructureNode.ContextType. The JpaStructureNode.ContextType implements hashCode, but JpaPlatform (GenericJpaPlatorm) doesn't.
Since a JPA platform is created in the jpa post-build listener when rebuilding a project, JpaDetailsView allocates a new page manager for all nodes. 
This causes a memory leak because every page manager allocates SWT resources and adds a lot of JPA listeners. 
The page managers are disposed when closing the JpaDetailsView, but users rarely close this view.

The attached patch (against WTP 3.4.2RC2 - the v201301092252 tag) fixes the issue by adding the equals/hashCode methods to GenericJpaPlatform. I think it is enough to add the id field to equals/hashCode because it is unique.

Other implementations of the JPAPlatform interface would also need to implement equals/hashCode.

The issue doesn't happen in the jpa master because it caches the platform when the platform is created the first time and doesn't create it again.
Comment 1 Snjezana Peco CLA 2013-01-30 13:02:24 EST
Created attachment 226334 [details]
A patch
Comment 2 Brian Vosburgh CLA 2013-06-04 15:33:11 EDT
I'm sorry we took so long to get to this bug; as we had a few miscommunications and did not realize this concerned Juno SR2. As you say in the initial description, this is not a problem in Kepler. But this bug probably came in too late to be part of Juno SR2; as we had already finished and tested our final build. I am setting the Target Milestone to 3.2.3; so if we ever have an SR3 or something like that, this bug will be fixed there.

Thank you for the patch. I think a safer fix in an SR would be to change the implementations of JpaStructureNode.ContextType.hashCode() and .equals(Object) to use JpaPlatform.getId() instead of using the JpaPlatform directly. This is a bit safer than changing the contract of JpaPlatform for adopters.

Also, I think a workaround to this leak would be to simply close and re-open the JPA Details view.
Comment 3 Mickael Istria CLA 2014-02-06 10:21:14 EST
Fixed in Kepler and later.
https://dev.eclipse.org/mhonarc/lists/wtp-dev/msg08911.html
Comment 4 wei cai CLA 2014-07-01 02:37:23 EDT
Created attachment 244692 [details]
Sample project to reproduce the issue

Sample project to reproduce the issue

Steps:
Import latest m2e code from master branch
debug as Eclipse Application
Import the maven project from attached.
Comment 5 wei cai CLA 2014-07-01 02:38:42 EDT
(In reply to wei cai from comment #4)
> Created attachment 244692 [details]
> Sample project to reproduce the issue
> 
> Sample project to reproduce the issue
> 
> Steps:
> Import latest m2e code from master branch
> debug as Eclipse Application
> Import the maven project from attached.

Wrong post, sorry for the spam