mirror of https://github.com/apache/openjpa.git
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
This commit is contained in:
parent
9168ab0032
commit
4d5c43ad78
|
@ -21,15 +21,13 @@ 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;
|
||||
|
@ -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<Class<?>, Map<String, Method>> getterMethodCache =
|
||||
new WeakHashMap<Class<?>, Map<String, Method>>();
|
||||
private static Map<Class<?>, Map<String, Method>> setterMethodCache =
|
||||
new WeakHashMap<Class<?>, Map<String, Method>>();
|
||||
private static Map<Class<?>, Set<String>> beanPropertiesNameCache =
|
||||
new WeakHashMap<Class<?>, Set<String>>();
|
||||
|
||||
private static Method getGetterMethod(Class<?> cls, String prop) {
|
||||
Method rtnMethod = null;
|
||||
Map<String, Method> clsMap = getterMethodCache.get(cls);
|
||||
if (clsMap != null) {
|
||||
rtnMethod = clsMap.get(prop);
|
||||
}
|
||||
return rtnMethod;
|
||||
}
|
||||
|
||||
private static void setGetterMethod(Class<?> cls, String prop,
|
||||
Method method) {
|
||||
Map<String, Method> clsMap = getterMethodCache.get(cls);
|
||||
if (clsMap == null) {
|
||||
clsMap = new HashMap<String, Method>();
|
||||
getterMethodCache.put(cls, clsMap);
|
||||
}
|
||||
clsMap.put(prop, method);
|
||||
}
|
||||
|
||||
private static Method getSetterMethod(Class<?> cls, String prop) {
|
||||
Method rtnMethod = null;
|
||||
Map<String, Method> clsMap = setterMethodCache.get(cls);
|
||||
if (clsMap != null) {
|
||||
rtnMethod = clsMap.get(prop);
|
||||
}
|
||||
return rtnMethod;
|
||||
}
|
||||
|
||||
private static void setSetterMethod(Class<?> cls, String prop,
|
||||
Method method) {
|
||||
Map<String, Method> clsMap = setterMethodCache.get(cls);
|
||||
if (clsMap == null) {
|
||||
clsMap = new HashMap<String, Method>();
|
||||
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<prop> or is<prop> 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<String> getBeanStylePropertyNames(Class c) {
|
||||
if (c == null)
|
||||
return Collections.EMPTY_SET;
|
||||
Set<String> result = beanPropertiesNameCache.get(c);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
Method[] methods = c.getMethods();
|
||||
if (methods == null || methods.length < 2)
|
||||
return Collections.EMPTY_SET;
|
||||
/*Set<String>*/ result = new TreeSet<String>();
|
||||
Set<String> result = new TreeSet<String>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue