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