Retaining this information past second phase commit leads to it being
retained via dependencyResolver. Thus a series of reconfigurations will
invariably retain the complete history, which is completely wasteful and
constitutes a memory leak (with GC chains of ~1800 hops observed).
Change-Id: Id67b8813a1d55b36f0b55a1c96099b906bf313ad
Signed-off-by: Robert Varga <rovarga@cisco.com>
// close old module jmx registrator
oldInternalInfo.getModuleJMXRegistrator().close();
// close old module jmx registrator
oldInternalInfo.getModuleJMXRegistrator().close();
+
+ // We no longer need old internal info. Clear it out, so we do not create a serial leak evidenced
+ // by BUG-4514. The reason is that modules retain their resolver, which retains modules. If we retain
+ // the old module, we would have the complete reconfiguration history held in heap for no good reason.
+ entry.clearOldInternalInfo();
} else {
// new instance:
// wrap in readable dynamic mbean
} else {
// new instance:
// wrap in readable dynamic mbean
package org.opendaylight.controller.config.manager.impl.dependencyresolver;
import com.google.common.base.Preconditions;
package org.opendaylight.controller.config.manager.impl.dependencyresolver;
import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo;
import javax.annotation.Nullable;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo;
private final ModuleIdentifier name;
private final Module proxiedModule, realModule;
private final ModuleFactory moduleFactory;
private final ModuleIdentifier name;
private final Module proxiedModule, realModule;
private final ModuleFactory moduleFactory;
- @Nullable
- private final ModuleInternalInfo maybeOldInternalInfo;
private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
private final boolean isDefaultBean;
private final BundleContext bundleContext;
private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
private final boolean isDefaultBean;
private final BundleContext bundleContext;
+ @Nullable private ModuleInternalInfo maybeOldInternalInfo;
public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
ModuleFactory moduleFactory,
public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
ModuleFactory moduleFactory,
- @Nullable
- public ModuleInternalInfo getOldInternalInfo() {
+ @Nonnull public ModuleInternalInfo getOldInternalInfo() {
return Preconditions.checkNotNull(maybeOldInternalInfo);
}
return Preconditions.checkNotNull(maybeOldInternalInfo);
}
+ public void clearOldInternalInfo() {
+ Preconditions.checkState(maybeOldInternalInfo != null, "No old internal info present");
+ maybeOldInternalInfo = null;
+ }
+
public TransactionModuleJMXRegistration getTransactionModuleJMXRegistration() {
return transactionModuleJMXRegistration;
}
public TransactionModuleJMXRegistration getTransactionModuleJMXRegistration() {
return transactionModuleJMXRegistration;
}