summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslaws <slaws@13f79535-47bb-0310-9956-ffa450edef68>2012-03-22 15:53:41 +0000
committerslaws <slaws@13f79535-47bb-0310-9956-ffa450edef68>2012-03-22 15:53:41 +0000
commit73da1fdb893118d67777a2e8962965d2336ca6e2 (patch)
tree9bf7b022e9596480521f05f49638fbe3e679a2a1
parenta16f36a53eaefe3e6f60df7537baecb2ab6f9a11 (diff)
TUSCANY-4034 - plug a few more potential memory leaks
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1303855 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java3
-rw-r--r--sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleProxyFactory.java3
-rw-r--r--sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java8
-rw-r--r--sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java32
-rw-r--r--sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java15
-rw-r--r--sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java5
-rw-r--r--sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/FaultBeanGenerator.java9
-rw-r--r--sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/WrapperBeanGenerator.java17
-rw-r--r--sca-java-2.x/trunk/testing/itest/performance/performance-test/src/test/java/org/apache/tuscany/sca/test/performance/PerformanceTestCase.java47
9 files changed, 128 insertions, 11 deletions
diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java
index cb2c01f7d6..a597f8b1ee 100644
--- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java
+++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CglibProxyFactory.java
@@ -149,4 +149,7 @@ public class CglibProxyFactory implements ProxyFactory {
}
+ public void removeProxiesForContribution(ClassLoader contributionClassloader){
+ // do nothing, no cache to clear
+ }
}
diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleProxyFactory.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleProxyFactory.java
index 049c73f258..3cb9445d2d 100644
--- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleProxyFactory.java
+++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ExtensibleProxyFactory.java
@@ -122,4 +122,7 @@ public class ExtensibleProxyFactory implements ProxyFactory {
return interfaceFactory.isProxyClass(clazz) || (classFactory != null && classFactory.isProxyClass(clazz));
}
+ public void removeProxiesForContribution(ClassLoader contributionClassloader){
+ // do nothing, no cache to clear
+ }
}
diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java
index f2d272757d..8d9612315a 100644
--- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java
+++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/ProxyFactory.java
@@ -84,5 +84,13 @@ public interface ProxyFactory {
* @return true if the class is a generated proxy class by this factory
*/
boolean isProxyClass(Class<?> clazz);
+
+ /**
+ * Allow cached proxies to be removed when a contribution is removed. The proxy
+ * cache holds the application interface so will pin the contribution classloader
+ *
+ * @param contributionClassloader the classloader of the contribution being removed
+ */
+ void removeProxiesForContribution(ClassLoader contributionClassloader);
}
diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
index a9a28d434a..7163357042 100644
--- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
+++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
@@ -24,11 +24,15 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Future;
+import javax.xml.bind.JAXBContext;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
@@ -213,4 +217,32 @@ public class JDKProxyFactory implements ProxyFactory, LifeCycleListener {
public void stop() {
cache.clear();
}
+
+ public void removeProxiesForContribution(ClassLoader contributionClassloader){
+ try {
+ synchronized(cache) {
+ Set<Class<?>> objSet = cache.keySet();
+ List<Class<?>> toRemove = new ArrayList<Class<?>>();
+ Iterator<Class<?>> i = objSet.iterator();
+ loop:
+ while(i.hasNext()) {
+ Class<?> cls = i.next();
+ ClassLoader cl = cls.getClassLoader();
+ while (cl != null){
+ if (cl == contributionClassloader){
+ toRemove.add(cls);
+ break loop;
+ }
+ // take account of generated classes
+ cl = cl.getParent();
+ }
+ }
+ for (Class<?> cls : toRemove){
+ cache.remove(cls);
+ }
+ }
+ } catch(Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
}
diff --git a/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java b/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java
index 456c4ef7b6..27f00be0ba 100644
--- a/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java
+++ b/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java
@@ -54,6 +54,8 @@ import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint;
import org.apache.tuscany.sca.databinding.jaxb.JAXBContextHelper;
import org.apache.tuscany.sca.deployment.Deployer;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
@@ -90,6 +92,8 @@ public class NodeImpl implements Node {
private boolean quietLogging;
private boolean releaseOnUnload;
+
+ private ContributionListener contributionListener;
public NodeImpl(Deployer deployer,
CompositeActivator compositeActivator,
@@ -107,7 +111,7 @@ public class NodeImpl implements Node {
utilityExtensionPoint.getUtility(ActiveNodes.class).getActiveNodes().add(this);
- domainRegistry.addContributionListener(new ContributionListener() {
+ contributionListener = new ContributionListener() {
public void contributionInstalled(String uri) {
// Do nothing
}
@@ -126,7 +130,9 @@ public class NodeImpl implements Node {
}
}
}
- });
+ };
+
+ this.domainRegistry.addContributionListener(contributionListener);
endpointsIncludeDomainName = !TuscanyRuntime.DEFAUL_DOMAIN_NAME.equals(domainRegistry.getDomainName());
@@ -248,6 +254,10 @@ public class NodeImpl implements Node {
JavaInterfaceFactory javaInterfaceFactory = factoryExtensionPoint.getFactory(JavaInterfaceFactory.class);
javaInterfaceFactory.removeInterfacesForContribution(contributionClassloader);
+
+ ProxyFactoryExtensionPoint proxyFactoryExtensionPoint = extensionPointRegistry.getExtensionPoint(ProxyFactoryExtensionPoint.class);
+ ProxyFactory interfaceProxyFactory = proxyFactoryExtensionPoint.getInterfaceProxyFactory();
+ interfaceProxyFactory.removeProxiesForContribution(contributionClassloader);
}
domainRegistry.uninstallContribution(contributionURI);
@@ -587,6 +597,7 @@ public class NodeImpl implements Node {
startedComposites.clear();
stoppedComposites.clear();
extensionPointRegistry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(ActiveNodes.class).getActiveNodes().remove(this);
+ domainRegistry.removeContributionListener(contributionListener);
if (tuscanyRuntime != null) {
tuscanyRuntime.stop();
}
diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java
index ca39ec0e62..923d13cd5e 100644
--- a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java
+++ b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java
@@ -20,6 +20,7 @@
package org.apache.tuscany.sca.interfacedef.java.jaxws;
import java.lang.annotation.Annotation;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -119,8 +120,8 @@ public abstract class BaseBeanGenerator implements Opcodes {
JAVA_KEYWORDS.put("enum", "_enum");
}
- protected static final Map<Object, Class<?>> generatedClasses =
- Collections.synchronizedMap(new WeakHashMap<Object, Class<?>>());
+ protected static final Map<Object, WeakReference<Class<?>>> generatedClasses =
+ Collections.synchronizedMap(new WeakHashMap<Object, WeakReference<Class<?>>>());
protected XMLAdapterExtensionPoint xmlAdapters;
diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/FaultBeanGenerator.java b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/FaultBeanGenerator.java
index 2e82428f7e..28fd2afe73 100644
--- a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/FaultBeanGenerator.java
+++ b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/FaultBeanGenerator.java
@@ -23,6 +23,7 @@ import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -108,7 +109,11 @@ public class FaultBeanGenerator extends BaseBeanGenerator {
public Class<?> generate(Class<? extends Throwable> exceptionClass, GeneratedClassLoader cl, Operation operation) {
synchronized (exceptionClass) {
QName element = getElementName(exceptionClass, operation);
- Class<?> faultBeanClass = generatedClasses.get(element);
+ WeakReference<Class<?>> wr = generatedClasses.get(element);
+ Class<?> faultBeanClass = null;
+ if (wr != null){
+ faultBeanClass = wr.get();
+ }
if (faultBeanClass == null) {
// TUSCANY-3283 - all generated classes (including exception) should go in the namespace
@@ -122,7 +127,7 @@ public class FaultBeanGenerator extends BaseBeanGenerator {
String classSignature = "L" + classDescriptor + ";";
faultBeanClass = generate(classDescriptor, classSignature, namespace, name, getProperties(exceptionClass), cl);
- generatedClasses.put(element, faultBeanClass);
+ generatedClasses.put(element, new WeakReference<Class<?>>(faultBeanClass));
}
return faultBeanClass;
}
diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/WrapperBeanGenerator.java b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/WrapperBeanGenerator.java
index 42151464a4..ab7036c0ce 100644
--- a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/WrapperBeanGenerator.java
+++ b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/WrapperBeanGenerator.java
@@ -20,6 +20,7 @@
package org.apache.tuscany.sca.interfacedef.java.jaxws;
import java.lang.annotation.Annotation;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -64,7 +65,11 @@ public class WrapperBeanGenerator extends BaseBeanGenerator {
GeneratedClassLoader cl) {
synchronized (m.getDeclaringClass()) {
MethodKey key = new MethodKey(m, true);
- Class<?> wrapperClass = generatedClasses.get(key);
+ WeakReference<Class<?>> wr = generatedClasses.get(key);
+ Class<?> wrapperClass = null;
+ if (wr != null){
+ wrapperClass = wr.get();
+ }
if (wrapperClass == null) {
String wrapperClassDescriptor = wrapperClassName.replace('.', '/');
String wrapperClassSignature = "L" + wrapperClassDescriptor + ";";
@@ -110,7 +115,7 @@ public class WrapperBeanGenerator extends BaseBeanGenerator {
wrapperClass =
generate(wrapperClassDescriptor, wrapperClassSignature, wrapperNamespace, wrapperName, properties
.toArray(new BeanProperty[properties.size()]), cl);
- generatedClasses.put(key, wrapperClass);
+ generatedClasses.put(key, new WeakReference<Class<?>>(wrapperClass));
}
return wrapperClass;
@@ -134,7 +139,11 @@ public class WrapperBeanGenerator extends BaseBeanGenerator {
GeneratedClassLoader cl) {
synchronized (m.getDeclaringClass()) {
MethodKey key = new MethodKey(m, false);
- Class<?> wrapperClass = generatedClasses.get(key);
+ WeakReference<Class<?>> wr = generatedClasses.get(key);
+ Class<?> wrapperClass = null;
+ if (wr != null){
+ wrapperClass = wr.get();
+ }
if (wrapperClass == null) {
String wrapperClassDescriptor = wrapperClassName.replace('.', '/');
String wrapperClassSignature = "L" + wrapperClassDescriptor + ";";
@@ -212,7 +221,7 @@ public class WrapperBeanGenerator extends BaseBeanGenerator {
wrapperClass =
generate(wrapperClassDescriptor, wrapperClassSignature, wrapperNamespace, wrapperName, properties
.toArray(new BeanProperty[properties.size()]), cl);
- generatedClasses.put(key, wrapperClass);
+ generatedClasses.put(key, new WeakReference<Class<?>>(wrapperClass));
}
return wrapperClass;
diff --git a/sca-java-2.x/trunk/testing/itest/performance/performance-test/src/test/java/org/apache/tuscany/sca/test/performance/PerformanceTestCase.java b/sca-java-2.x/trunk/testing/itest/performance/performance-test/src/test/java/org/apache/tuscany/sca/test/performance/PerformanceTestCase.java
index 329eea6a3d..d05ed1fd74 100644
--- a/sca-java-2.x/trunk/testing/itest/performance/performance-test/src/test/java/org/apache/tuscany/sca/test/performance/PerformanceTestCase.java
+++ b/sca-java-2.x/trunk/testing/itest/performance/performance-test/src/test/java/org/apache/tuscany/sca/test/performance/PerformanceTestCase.java
@@ -78,6 +78,33 @@ public class PerformanceTestCase {
resultsFile.flush();
resultsFile.close();
}
+
+ @Test
+ public void testNodeStartStop() {
+ dumpHeapStart("testInstallUninstall");
+
+ printRuntimeStats("createRuntime");
+
+ createRuntime();
+
+ callNodeStartStopRepeatedly(100);
+
+ waitForInput();
+
+ dumpHeapEnd("testInstallUninstall_postNodeStop");
+
+ printRuntimeStats("stopRuntime");
+
+ stopRuntime();
+
+ printRuntimeStats("destroyRuntime");
+
+ destroyRuntime();
+
+ printRuntimeStats("End");
+
+ dumpHeapEnd("testInstallUninstall_postStop");
+ }
@Test
public void testInstallUninstall() {
@@ -91,7 +118,7 @@ public class PerformanceTestCase {
createNode();
- callInstallUninstallRepeatedly(10);
+ callInstallUninstallRepeatedly(100);
dumpHeapEnd("testInstallUninstall_postUninstall");
@@ -187,6 +214,24 @@ public class PerformanceTestCase {
// ============================================================
+ public void callNodeStartStopRepeatedly(int repeatCount) {
+ for (int i =0; i < repeatCount; i++){
+ printRuntimeStats("createNode");
+
+ createNode();
+
+ callInstallUninstallRepeatedly(1);
+
+ printRuntimeStats("stopNode");
+
+ stopNode();
+
+ printRuntimeStats("destroyNode");
+
+ destroyNode();
+ }
+ }
+
public void callInstallUninstallRepeatedly(int repeatCount) {
for (int i =0; i < repeatCount; i++){
printRuntimeStats("install/unistall contribution");