Author: davsclaus
Date: Mon Feb 27 07:06:00 2012
New Revision: 1294044
URL: http://svn.apache.org/viewvc?rev=1294044&view=rev
Log:
CAMEL-5045: Fixed memory leak when removing routes.
Modified:
camel/branches/camel-2.9.x/ (props changed)
camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
Propchange: camel/branches/camel-2.9.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 27 07:06:00 2012
@@ -1 +1 @@
-/camel/trunk:1243046,1243057,1243234,1244518,1244644,1244859,1244861,1244864,1244870,1244872,1245021,1291555,1291727,1291848,1291864,1292114,1292384,1292725,1292760,1292767,1293079,1293268,1293288,1293330,1293590,1293828,1293852
+/camel/trunk:1243046,1243057,1243234,1244518,1244644,1244859,1244861,1244864,1244870,1244872,1245021,1291555,1291727,1291848,1291864,1292114,1292384,1292725,1292760,1292767,1293079,1293268,1293288,1293330,1293590,1293828,1293852,1293855
Propchange: camel/branches/camel-2.9.x/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified:
camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
URL:
http://svn.apache.org/viewvc/camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java?rev=1294044&r1=1294043&r2=1294044&view=diff
==============================================================================
---
camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
(original)
+++
camel/branches/camel-2.9.x/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
Mon Feb 27 07:06:00 2012
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -64,6 +65,7 @@ import org.apache.camel.model.OnCompleti
import org.apache.camel.model.OnExceptionDefinition;
import org.apache.camel.model.PolicyDefinition;
import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.model.ProcessorDefinitionHelper;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.processor.interceptor.Tracer;
import org.apache.camel.spi.CamelContextNameStrategy;
@@ -94,6 +96,8 @@ import org.slf4j.LoggerFactory;
public class DefaultManagementLifecycleStrategy extends ServiceSupport
implements LifecycleStrategy, CamelContextAware {
private static final Logger LOG =
LoggerFactory.getLogger(DefaultManagementLifecycleStrategy.class);
+ // the wrapped processors is for performance counters, which are in use
for the created routes
+ // when a route is removed, we should remove the associated processors
from this map
private final Map<Processor, KeyValueHolder<ProcessorDefinition,
InstrumentationProcessor>> wrappedProcessors =
new HashMap<Processor, KeyValueHolder<ProcessorDefinition,
InstrumentationProcessor>>();
private final List<PreRegisterService> preServices = new
ArrayList<PreRegisterService>();
@@ -528,7 +532,14 @@ public class DefaultManagementLifecycleS
} catch (Exception e) {
LOG.warn("Could not unregister Route MBean", e);
}
+
+ // remove from known routes ids, as the route has been removed
+ knowRouteIds.remove(route.getId());
}
+
+ // after the routes has been removed, we should clear the wrapped
processors as we no longer need them
+ // as they were just a provisional map used during creation of routes
+ removeWrappedProcessorsForRoutes(routes);
}
public void onErrorHandlerAdd(RouteContext routeContext, Processor
errorHandler, ErrorHandlerFactory errorHandlerBuilder) {
@@ -600,7 +611,30 @@ public class DefaultManagementLifecycleS
routeContext.setManagedInterceptStrategy(new
InstrumentationInterceptStrategy(registeredCounters, wrappedProcessors));
}
- @SuppressWarnings("unchecked")
+ /**
+ * Removes the wrapped processors for the given routes, as they are no
longer in use.
+ * <p/>
+ * This is needed to avoid accumulating memory, if a lot of routes is
being added and removed.
+ *
+ * @param routes the routes
+ */
+ private void removeWrappedProcessorsForRoutes(Collection<Route> routes) {
+ // loop the routes, and remove the route associated wrapped
processors, as they are no longer in use
+ for (Route route : routes) {
+ String id = route.getId();
+
+ Iterator<KeyValueHolder<ProcessorDefinition,
InstrumentationProcessor>> it = wrappedProcessors.values().iterator();
+ while (it.hasNext()) {
+ KeyValueHolder<ProcessorDefinition, InstrumentationProcessor>
holder = it.next();
+ RouteDefinition def =
ProcessorDefinitionHelper.getRoute(holder.getKey());
+ if (def != null && id.equals(def.getId())) {
+ it.remove();
+ }
+ }
+ }
+
+ }
+
private void registerPerformanceCounters(RouteContext routeContext,
ProcessorDefinition processor,
Map<ProcessorDefinition,
PerformanceCounter> registeredCounters) {
@@ -767,6 +801,8 @@ public class DefaultManagementLifecycleS
initialized = false;
knowRouteIds.clear();
preServices.clear();
+ wrappedProcessors.clear();
+ managedTracers.clear();
ServiceHelper.stopService(timerListenerManager);
}