From 4d5c43ad78b6b2c326bc53044c0efbf905771137 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Wed, 3 Jun 2009 16:58:14 +0000 Subject: [PATCH] OPENJPA-1113 - Revert changes back to previous levels: Reflection:743396 & AbstractBrokerFactory 768588. I have verified that the latest changes associated to this issue did not caused any memory leak by observing/dumping the static cache sizes in the Reflection class. The emf.close() method cleared out the cache, i.e. HashMap.size() == 0. From looking at the memory usage of the JVM that invoked the test in persistence-jdbc module, the memory usage continues to grow even without the changes committed by this issue. Therefore there is some memory leak somewhere either in the test case or the provider code. The OOM condition only occurs with Sun JDK, IBM JDK works ok. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@781473 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/openjpa/enhance/Reflection.java | 93 +++---------------- .../openjpa/kernel/AbstractBrokerFactory.java | 15 ++- 2 files changed, 19 insertions(+), 89 deletions(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java index a37ce6d8f..8023ab98b 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java @@ -21,22 +21,20 @@ package org.apache.openjpa.enhance; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.security.AccessController; import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import java.util.Set; import java.util.TreeSet; -import java.util.WeakHashMap; import org.apache.commons.lang.StringUtils; import org.apache.openjpa.lib.util.J2DoPrivHelper; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Reflectable; -import org.apache.openjpa.util.GeneralException; -import org.apache.openjpa.util.UserException; +import org.apache.openjpa.util.GeneralException; +import org.apache.openjpa.util.UserException; /** * Reflection utilities used to support and augment enhancement. Used both @@ -49,84 +47,27 @@ public class Reflection { private static final Localizer _loc = Localizer.forPackage (Reflection.class); - // Weak HashMap caches of getter/setter/beanProperty methods - private static Map, Map> getterMethodCache = - new WeakHashMap, Map>(); - private static Map, Map> setterMethodCache = - new WeakHashMap, Map>(); - private static Map, Set> beanPropertiesNameCache = - new WeakHashMap, Set>(); - - private static Method getGetterMethod(Class cls, String prop) { - Method rtnMethod = null; - Map clsMap = getterMethodCache.get(cls); - if (clsMap != null) { - rtnMethod = clsMap.get(prop); - } - return rtnMethod; - } - - private static void setGetterMethod(Class cls, String prop, - Method method) { - Map clsMap = getterMethodCache.get(cls); - if (clsMap == null) { - clsMap = new HashMap(); - getterMethodCache.put(cls, clsMap); - } - clsMap.put(prop, method); - } - - private static Method getSetterMethod(Class cls, String prop) { - Method rtnMethod = null; - Map clsMap = setterMethodCache.get(cls); - if (clsMap != null) { - rtnMethod = clsMap.get(prop); - } - return rtnMethod; - } - - private static void setSetterMethod(Class cls, String prop, - Method method) { - Map clsMap = setterMethodCache.get(cls); - if (clsMap == null) { - clsMap = new HashMap(); - setterMethodCache.put(cls, clsMap); - } - clsMap.put(prop, method); - } - - public static void flushCaches() { - getterMethodCache.clear(); - setterMethodCache.clear(); - beanPropertiesNameCache.clear(); - } - /** * Return the getter method matching the given property name, optionally * throwing an exception if none. */ public static Method findGetter(Class cls, String prop, boolean mustExist) { - Method m = getGetterMethod(cls, prop); - if (m != null) { - return m; - } - String capProp = StringUtils.capitalize(prop); + prop = StringUtils.capitalize(prop); + String name = "get" + prop; + Method m; try { // this algorithm searches for a get or is method in // a breadth-first manner. for (Class c = cls; c != null && c != Object.class; c = c.getSuperclass()) { - m = getDeclaredMethod(c, "get" + capProp, null); + m = getDeclaredMethod(c, name, null); if (m != null) { - setGetterMethod(cls, prop, m); return m; } else { - m = getDeclaredMethod(c, "is" + capProp, null); + m = getDeclaredMethod(c, "is" + prop, null); if (m != null && (m.getReturnType() == boolean.class - || m.getReturnType() == Boolean.class)) { - setGetterMethod(cls, prop, m); + || m.getReturnType() == Boolean.class)) return m; - } } } } catch (Exception e) { @@ -154,19 +95,14 @@ public class Reflection { */ public static Method findSetter(Class cls, String prop, Class param, boolean mustExist) { - Method m = getSetterMethod(cls, prop); - if (m != null) { - return m; - } String name = "set" + StringUtils.capitalize(prop); + Method m; try { for (Class c = cls; c != null && c != Object.class; c = c.getSuperclass()) { m = getDeclaredMethod(c, name, param); - if (m != null) { - setSetterMethod(cls, prop, m); + if (m != null) return m; - } } } catch (Exception e) { throw new GeneralException(e); @@ -838,14 +774,10 @@ public class Reflection { public static Set getBeanStylePropertyNames(Class c) { if (c == null) return Collections.EMPTY_SET; - Set result = beanPropertiesNameCache.get(c); - if (result != null) { - return result; - } Method[] methods = c.getMethods(); if (methods == null || methods.length < 2) return Collections.EMPTY_SET; - /*Set*/ result = new TreeSet(); + Set result = new TreeSet(); for (Method m : methods) { if (m.getName().startsWith("get")) { if (!canReflect(m)) @@ -863,7 +795,6 @@ public class Reflection { } } } - beanPropertiesNameCache.put(c, result); return result; } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java index c6c9c785c..0f241939f 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java @@ -31,26 +31,23 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReentrantLock; import javax.transaction.Status; import javax.transaction.Synchronization; import javax.transaction.Transaction; import javax.transaction.TransactionManager; -import org.apache.commons.collections.set.MapBackedSet; import org.apache.commons.lang.StringUtils; -import org.apache.openjpa.conf.BrokerValue; +import org.apache.commons.collections.set.MapBackedSet; import org.apache.openjpa.conf.OpenJPAConfiguration; -import org.apache.openjpa.conf.OpenJPAConfigurationImpl; import org.apache.openjpa.conf.OpenJPAVersion; +import org.apache.openjpa.conf.BrokerValue; +import org.apache.openjpa.conf.OpenJPAConfigurationImpl; import org.apache.openjpa.datacache.DataCacheStoreManager; import org.apache.openjpa.ee.ManagedRuntime; -import org.apache.openjpa.enhance.ManagedClassSubclasser; import org.apache.openjpa.enhance.PCRegistry; import org.apache.openjpa.enhance.PersistenceCapable; -import org.apache.openjpa.enhance.Reflection; +import org.apache.openjpa.enhance.ManagedClassSubclasser; import org.apache.openjpa.event.BrokerFactoryEvent; import org.apache.openjpa.event.RemoteCommitEventManager; import org.apache.openjpa.lib.conf.Configuration; @@ -58,7 +55,9 @@ import org.apache.openjpa.lib.conf.Configurations; import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.lib.util.J2DoPrivHelper; import org.apache.openjpa.lib.util.Localizer; +import java.util.concurrent.ConcurrentHashMap; import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet; +import java.util.concurrent.locks.ReentrantLock; import org.apache.openjpa.meta.MetaDataRepository; import org.apache.openjpa.util.GeneralException; import org.apache.openjpa.util.InvalidStateException; @@ -411,7 +410,7 @@ public abstract class AbstractBrokerFactory PCRegistry.removeRegisterClassListener (_conf.getMetaDataRepositoryInstance()); } - Reflection.flushCaches(); + _conf.close(); _closed = true; Log log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);