Hi all,

I think that resin (at least version 3.1, but most probably 4.0 too) suffers
from a critical classloader leak which may cause that the memory occupied
by an application will not get released when destroying its servlet context
(stopping/redeploying the application).
As an result, further restarts/redeployments will sooner or later  
result in an OutOfMemoryError.

Please have a look at  

On line 51 there's a WeakHashMap defined, which maps the classloader
to the corresponding PersistenceProvider instances:

   private static WeakHashMap<ClassLoader,PersistenceProvider[]>
     _providerMap = new WeakHashMap<ClassLoader,PersistenceProvider[]>();

The problem is that a PersistenceProvider instance may reference the  
key indirectly
(which is at least true when not using Amber, e.g. EclipseLink)
The loaded class will of course reference its classloader, which is  
the web application's classloader.
However according to the javadocs this will prevent the removal of the entry:

"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."

With the consequence that the EnvironmentClassLoader cannot be garbage  

When looking at the GC roots (for a classloader from a stopped application)
this can be seen easily:

Class Name                                                              
             | Shallow Heap | Retained Heap
com.caucho.loader.EnvironmentClassLoader @ 0xe68362d0                   
             |          376 |   131.077.664
'- <classloader> class org.eclipse.persistence.jpa.PersistenceProvider  
@ 0xd3bda6d8|            0 |             0
    '- <class> org.eclipse.persistence.jpa.PersistenceProvider @  
0xe7bb2010         |           24 |            40
       '- [3] javax.persistence.spi.PersistenceProvider[4] @  
0xe7bb2020             |           56 |           144
          '- value java.util.WeakHashMap$Entry @ 0xe7c72ca8             
              |           72 |           432
             '- [11] java.util.WeakHashMap$Entry[16] @ 0xe118fc18       
              |          152 |           800
                '- table java.util.WeakHashMap @ 0xe118fbe8             
              |           72 |           928
                   '- _providerMap class javax.persistence.Persistence  
@ 0xd1fc55a8 |           32 |           960
                      '- [1152] java.lang.Object[1280] @ 0xe0b40378     
              |       10.264 |     1.774.424

As you can see, the second last line (_providerMap class  
javax.persistence.Persistence @ 0xd1fc55a8) which is actually
a caucho class, references the old EnvironmentClassLoader.
So in my case, 131 MB will not get released.

If I am right - is there a workaround available?
(Is it possible to configure the EnvironmentClassLoader that it will not load
the PersistenceProvider/Persistence class from Amber but from the JPA  
implementation which my application provides?)

Thank you and best regards,

resin-interest mailing list

Reply via email to