Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 353155 - EclipseLink classloader leak?
Summary: EclipseLink classloader leak?
Status: CLOSED DUPLICATE of bug 331098
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 critical (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-07-26 15:16 EDT by Patric Rufflar CLA
Modified: 2022-06-09 10:27 EDT (History)
1 user (show)

See Also:


Attachments
GC roots form a websphere 7 heap dump (9.99 KB, text/plain)
2012-12-06 13:44 EST, Patric Rufflar CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Patric Rufflar CLA 2011-07-26 15:16:00 EDT
Build Identifier: 2.3.0

I experience a classloader leak when deploying my application at caucho's resin 4.0.20 application server.

Resin loads any JPA implementation with the global classloader (which differs from other servers like tomcat, which loads the JPA implementation with the web application's classloader).

When using a custom SessionEventListener, which is a class of my application, EclipseLink holds a reference to this class.
As a result, classes loaded by resin's global classloader hold a reference to classes of the web application's classloader, causing that the web application's classloader cannot be garbage collected, even when the web application has been stopped.

I initially thought that this is a bug in Resin's PersistenceProvider implementation.
I opened a bug report but the technical lead stated that this is not a bug at their application server but most probably an eclipselink bug.

Maybe you can enlighten me (or tell me what I am doing wrong).

For more information please have a look at my initial bug report on their site:
http://bugs.caucho.com/view.php?id=4684


Reproducible: Always
Comment 1 Tom Ware CLA 2011-08-02 15:52:29 EDT
Can you elaborate on the specific steps causes the problem?  Are there two applications using the same persistence unit?  Is it an issue when you use an EntityManagerFactory once, stop using the application and then try to create a new one?  

Is there an exception?  What does it look like?

EclipseLink stores a static collection of it's "session" constructs.  These are indexed based on a name.  By default, that name is calculated based on the Root URL of the persistence unit, it's name and some of it's connection info.  It is possible that if two different applications ended up using the same session, there would be some issues in the Resin architecture.

Depending on what your usecase is the following might help:

1. Make sure you explicitly close your EntityManagerFactory when you are finished with it.
2. Have each application specify the persistence-unit-property, "eclipselink.sessoin-name" as a unique name.  You can specify that information in the map of properties passed into createEntityManagerFactory().
Comment 2 Tom Ware CLA 2011-08-15 08:22:44 EDT
Temporarily setting Priority to P3 based on the lack of information.

See this link for information about what this means:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines

See above for required information.
Comment 3 Patric Rufflar CLA 2012-12-06 13:43:00 EST
It seems that two different issues are involved here - one issue was indeed a resin one - this bug is finally fixed:
http://www.mail-archive.com/resin-interest@caucho.com/msg05359.html
http://bugs.caucho.com/view.php?id=4722


But it seems that there's another issue which is possibly causing a classloader leak - this one seems related to eclipselink or to be more precise, to the javax.persistence.spi package.

Have a look at javax.persistence.spi.PersistenceProviderResolverHolder (I am referring to the JPA 2.0 /eclipselink 2.3.3 version), line 87:

   private volatile WeakHashMap<ClassLoader, List<PersistenceProvider>> providers = new WeakHashMap<ClassLoader, List<PersistenceProvider>>();

We have a weak hashmap here with a ClassLoader as its (weak) key and a (strong referenced) List of PersistenceProvider objects.
Each PersistenceProvider are (usually) loaded by the ClassLoader which is the corresponding key.

Because they are loaded they still refer to the ClassLoader.
This is causing a reference cycle - the values of the WeakHashMap are referring to the weak key - causing the map entry to stay forever.
(Cite from the javadoc: "Implementation note: The value objects in a WeakHashMap are held by ordinary strong references. Thus care should be taken to ensure that value objects do not strongly refer to their own keys, either directly or indirectly, since that will prevent the keys from being discarded.")

As a result, the classloader and all loaded classes cannot be garbage collected.
(This is at least the case if the javax.persistence.* classes are loaded by a different (and more global) classloader than the eclipselink/PersistenceProvider classes - which is common in J2EE environments)

A heap dump (from a websphere 7 deployment) clearly shows this - have a look at the attachment which is showing the GC roots to the Classloader after the web application has been stopped.

Because other JPA implementations and even J2EE containers provide their own javax.persistence.jar - which are usually derived from the eclipselink RI codebase - it's likely that this issue might have a major impact on all those products - which increases the impact of this issue even more.
Comment 4 Patric Rufflar CLA 2012-12-06 13:44:16 EST
Created attachment 224390 [details]
GC roots form a websphere 7 heap dump

(heap dump taken after web application has been stopped)
Comment 5 Tom Ware CLA 2012-12-07 07:32:34 EST

*** This bug has been marked as a duplicate of bug 331098 ***
Comment 6 Eclipse Webmaster CLA 2022-06-09 10:27:52 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink