I think the problem is that a class registers itself exactly once with the PCRegistry. So if we unregister it with EMF.close(), then if we were to subsequently create a new EMF, the class would no longer be registered.

If we are interested in discussing alternate approaches, though, the following just occurred to me: if the only problem preventing us from having PCRegistry classes as weak keys is that their value graph eventually hits on the template instance of the entity, we could just remove the template instance from the PCRegistry graph, and instead keep around a separate Map<Class:Object> of the class to the template instance in the EntityManagerFactory/BrokerFactory itself (which could be lazily initialized whenever the template instances are needed). That way, when the EMF is destroyed, there would be no template instances around to prevent the weak PCRegistry class keys from getting cleaned up.

The only hitch is that the registration of the template instance occurs in the enhancement bytecode of the entity itself, which allows us to deal with private/protected no-arg constructors (which we synthetically add if none exists) without having to muck around with security. We'd need to consider whether we are willing to sacrifice that.




On Aug 1, 2007, at 5:00 PM, Patrick Linskey wrote:

It would seem that we should be able to do something via EMF.close().
We'd probably want to do some sort of reference-counting to make sure
that we didn't unregister types that shouldn't be unregistered yet,
but it should be doable from there.

-Patrick

On 8/1/07, Kevin Sutter <[EMAIL PROTECTED]> wrote:
Pinaki,
The Embedder of OpenJPA would have to call this method (ie. Geronimo,
WebSphere, WebLogic, etc). Any application server that embeds OpenJPA may
have to call this method if they run into this memory leak.  From the
discussion on the dev mailing list, it sounds like this problem would be pervasive across all application servers. Thus far, Geronimo is the only
one that has reported the problem.

I realize that this is not ideal with the Embedder calling back into OpenJPA
to indicate that a classloader is no longer in service, but from the
discussions, it didn't sound like any other solution was going to suffice. And, it sounded like from Don's last post on OPENJPA-285 that they were getting antsy for some type of resolution. I figured that this change resolves the situation for now and if we come up with something better or
more generic, then we can change it or add to it later.

Kevin

On 8/1/07, Pinaki Poddar <[EMAIL PROTECTED]> wrote:

Kevin,
   Who calls PCRegistry.deRegister(ClassLoader cl)?


Pinaki Poddar
972.834.2865

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Wednesday, August 01, 2007 4:56 PM
To: [EMAIL PROTECTED]
Subject: svn commit: r561970 - in
/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa:
enhance/PCRegistry.java util/ImplHelper.java

Author: kwsutter
Date: Wed Aug  1 14:55:44 2007
New Revision: 561970

URL: http://svn.apache.org/viewvc?view=rev&rev=561970
Log:
OPENJPA-285. I am going ahead with the integration of Kevan's patches
for the two memory leaks found in OpenJPA while testing Geronimo.  I
will post more details in the Issue.

Modified:

openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ enhance/PC
Registry.java

openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ util/ImplH
elper.java

Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ enhance/PC
Registry.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/ main/java/ org/apache/openjpa/enhance/PCRegistry.java? view=diff&rev=561970&r1=56196
9&r2=561970
==================================================================== ====
======
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ enhance/PC
Registry.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ enhanc
+++ e/PCRegistry.java Wed Aug  1 14:55:44 2007
@@ -203,6 +203,23 @@
     }

     /**
+ * De-Register all metadata associated with the given ClassLoader.
+     * Allows ClassLoaders to be garbage collected.
+     *
+     * @param cl the ClassLoader
+     */
+    public static void deRegister(ClassLoader cl) {
+        synchronized (_metas) {
+ for (Iterator i = _metas.keySet().iterator(); i.hasNext();)
{
+                Class pcClass = (Class) i.next();
+                if (pcClass.getClassLoader() == cl) {
+                    _metas.remove(pcClass);
+                }
+            }
+        }
+    }
+
+    /**
      * Returns a collection of class objects of the registered
      * persistence-capable classes.
      */

Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ util/ImplH
elper.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/ main/java/ org/apache/openjpa/util/ImplHelper.java? view=diff&rev=561970&r1=561969&r
2=561970
==================================================================== ====
======
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ util/ImplH
elper.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ util/I
+++ mplHelper.java Wed Aug  1 14:55:44 2007
@@ -39,7 +39,6 @@
import org.apache.openjpa.lib.util.Closeable;
import org.apache.openjpa.lib.util.ReferenceMap;
import org.apache.openjpa.lib.util.UUIDGenerator;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
import
org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
@@ -244,7 +243,8 @@
         Boolean isAssignable = null;
         Map assignableTo = (Map) _assignableTypes.get(from);
         if (assignableTo == null) { // "to" cache doesn't exist, so
create it...
-            assignableTo = new ConcurrentHashMap();
+            assignableTo = new
ConcurrentReferenceHashMap(ReferenceMap.WEAK,
+                    ReferenceMap.HARD);
             _assignableTypes.put(from, assignableTo);
         } else { // "to" cache exists...
             isAssignable = (Boolean) assignableTo.get(to);



Notice: This email message, together with any attachments, may contain information of BEA Systems, Inc., its subsidiaries and affiliated entities, that may be confidential, proprietary, copyrighted and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email
and then delete it.




--
Patrick Linskey
202 669 5907

Reply via email to