package org.apache.catalina.core;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Valve;
+import org.apache.catalina.loader.WebappClassLoader;
import org.apache.catalina.startup.HostConfig;
import org.apache.catalina.valves.ValveBase;
import org.apache.tomcat.util.modeler.Registry;
*/
private boolean createDirs = true;
+
+ /**
+ * Track the class loaders for the child web applications so memory leaks
+ * can be detected.
+ */
+ private Map<ClassLoader, String> childClassLoaders =
+ new WeakHashMap<ClassLoader, String>();
+
// ------------------------------------------------------------- Properties
throw new IllegalArgumentException
(sm.getString("standardHost.notContext"));
super.addChild(child);
-
+
+ // Record a reference to the context's class loader to aid memory leak
+ // detection
+ if (child.getLoader() != null) {
+ childClassLoaders.put(child.getLoader().getClassLoader(),
+ child.getName());
+ }
}
/**
+ * Attempt to identify the contexts that have a class loader memory leak.
+ * This is usually triggered on context reload. Note: This method attempts
+ * to force a full garbage collection. This should be used with extreme
+ * caution on a production system.
+ */
+ public String[] findReloadedContextMemoryLeaks() {
+
+ System.gc();
+
+ List<String> result = new ArrayList<String>();
+
+ for (Map.Entry<ClassLoader, String> entry :
+ childClassLoaders.entrySet()) {
+ ClassLoader cl = entry.getKey();
+ if (cl instanceof WebappClassLoader) {
+ if (!((WebappClassLoader) cl).isStarted()) {
+ result.add(entry.getValue());
+ }
+ }
+ }
+
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
* Return the set of alias names for this Host. If none are defined,
* a zero length array is returned.
*/
<operation name="stop" description="Stop" impact="ACTION" returnType="void" />
<operation name="init" description="Init" impact="ACTION" returnType="void" />
<operation name="destroy" description="Destroy" impact="ACTION" returnType="void" />
+
+ <operation name="findReloadedContextMemoryLeaks"
+ description="Provide a list of contexts that have leaked memory on reload. This will attempt to force a full garbage collection. Use with extreme caution on prouction systems."
+ impact="ACTION"
+ returnType="[Ljava.lang.String;" />
+
</mbean>
<mbean name="StandardHostValve"