HADOOP-11105. MetricsSystemImpl could leak memory in registered callbacks. Contributed by Chuan Liu.
This commit is contained in:
parent
2c3da25fd7
commit
1942364ef1
|
@ -83,7 +83,12 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
private final Map<String, MetricsSource> allSources;
|
private final Map<String, MetricsSource> allSources;
|
||||||
private final Map<String, MetricsSinkAdapter> sinks;
|
private final Map<String, MetricsSinkAdapter> sinks;
|
||||||
private final Map<String, MetricsSink> allSinks;
|
private final Map<String, MetricsSink> allSinks;
|
||||||
|
|
||||||
|
// The callback list is used by register(Callback callback), while
|
||||||
|
// the callback map is used by register(String name, String desc, T sink)
|
||||||
private final List<Callback> callbacks;
|
private final List<Callback> callbacks;
|
||||||
|
private final Map<String, Callback> namedCallbacks;
|
||||||
|
|
||||||
private final MetricsCollectorImpl collector;
|
private final MetricsCollectorImpl collector;
|
||||||
private final MetricsRegistry registry = new MetricsRegistry(MS_NAME);
|
private final MetricsRegistry registry = new MetricsRegistry(MS_NAME);
|
||||||
@Metric({"Snapshot", "Snapshot stats"}) MutableStat snapshotStat;
|
@Metric({"Snapshot", "Snapshot stats"}) MutableStat snapshotStat;
|
||||||
|
@ -119,6 +124,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
sourceConfigs = Maps.newHashMap();
|
sourceConfigs = Maps.newHashMap();
|
||||||
sinkConfigs = Maps.newHashMap();
|
sinkConfigs = Maps.newHashMap();
|
||||||
callbacks = Lists.newArrayList();
|
callbacks = Lists.newArrayList();
|
||||||
|
namedCallbacks = Maps.newHashMap();
|
||||||
injectedTags = Lists.newArrayList();
|
injectedTags = Lists.newArrayList();
|
||||||
collector = new MetricsCollectorImpl();
|
collector = new MetricsCollectorImpl();
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
|
@ -178,11 +184,13 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (Callback cb : callbacks) cb.preStart();
|
for (Callback cb : callbacks) cb.preStart();
|
||||||
|
for (Callback cb : namedCallbacks.values()) cb.preStart();
|
||||||
configure(prefix);
|
configure(prefix);
|
||||||
startTimer();
|
startTimer();
|
||||||
monitoring = true;
|
monitoring = true;
|
||||||
LOG.info(prefix +" metrics system started");
|
LOG.info(prefix +" metrics system started");
|
||||||
for (Callback cb : callbacks) cb.postStart();
|
for (Callback cb : callbacks) cb.postStart();
|
||||||
|
for (Callback cb : namedCallbacks.values()) cb.postStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -198,6 +206,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (Callback cb : callbacks) cb.preStop();
|
for (Callback cb : callbacks) cb.preStop();
|
||||||
|
for (Callback cb : namedCallbacks.values()) cb.preStop();
|
||||||
LOG.info("Stopping "+ prefix +" metrics system...");
|
LOG.info("Stopping "+ prefix +" metrics system...");
|
||||||
stopTimer();
|
stopTimer();
|
||||||
stopSources();
|
stopSources();
|
||||||
|
@ -206,6 +215,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
monitoring = false;
|
monitoring = false;
|
||||||
LOG.info(prefix +" metrics system stopped.");
|
LOG.info(prefix +" metrics system stopped.");
|
||||||
for (Callback cb : callbacks) cb.postStop();
|
for (Callback cb : callbacks) cb.postStop();
|
||||||
|
for (Callback cb : namedCallbacks.values()) cb.postStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public synchronized <T>
|
@Override public synchronized <T>
|
||||||
|
@ -224,7 +234,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
}
|
}
|
||||||
// We want to re-register the source to pick up new config when the
|
// We want to re-register the source to pick up new config when the
|
||||||
// metrics system restarts.
|
// metrics system restarts.
|
||||||
register(new AbstractCallback() {
|
register(name, new AbstractCallback() {
|
||||||
@Override public void postStart() {
|
@Override public void postStart() {
|
||||||
registerSource(finalName, finalDesc, s);
|
registerSource(finalName, finalDesc, s);
|
||||||
}
|
}
|
||||||
|
@ -241,6 +251,9 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
if (allSources.containsKey(name)) {
|
if (allSources.containsKey(name)) {
|
||||||
allSources.remove(name);
|
allSources.remove(name);
|
||||||
}
|
}
|
||||||
|
if (namedCallbacks.containsKey(name)) {
|
||||||
|
namedCallbacks.remove(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized
|
synchronized
|
||||||
|
@ -268,7 +281,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
}
|
}
|
||||||
// We want to re-register the sink to pick up new config
|
// We want to re-register the sink to pick up new config
|
||||||
// when the metrics system restarts.
|
// when the metrics system restarts.
|
||||||
register(new AbstractCallback() {
|
register(name, new AbstractCallback() {
|
||||||
@Override public void postStart() {
|
@Override public void postStart() {
|
||||||
register(name, description, sink);
|
register(name, description, sink);
|
||||||
}
|
}
|
||||||
|
@ -289,9 +302,16 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void register(final Callback callback) {
|
public synchronized void register(final Callback callback) {
|
||||||
callbacks.add((Callback) Proxy.newProxyInstance(
|
callbacks.add((Callback) getProxyForCallback(callback));
|
||||||
callback.getClass().getClassLoader(), new Class<?>[] { Callback.class },
|
}
|
||||||
new InvocationHandler() {
|
|
||||||
|
private synchronized void register(String name, final Callback callback) {
|
||||||
|
namedCallbacks.put(name, (Callback) getProxyForCallback(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getProxyForCallback(final Callback callback) {
|
||||||
|
return Proxy.newProxyInstance(callback.getClass().getClassLoader(),
|
||||||
|
new Class<?>[] { Callback.class }, new InvocationHandler() {
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args)
|
public Object invoke(Object proxy, Method method, Object[] args)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
|
@ -303,7 +323,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -572,6 +592,7 @@ public class MetricsSystemImpl extends MetricsSystem implements MetricsSource {
|
||||||
allSources.clear();
|
allSources.clear();
|
||||||
allSinks.clear();
|
allSinks.clear();
|
||||||
callbacks.clear();
|
callbacks.clear();
|
||||||
|
namedCallbacks.clear();
|
||||||
if (mbeanName != null) {
|
if (mbeanName != null) {
|
||||||
MBeans.unregister(mbeanName);
|
MBeans.unregister(mbeanName);
|
||||||
mbeanName = null;
|
mbeanName = null;
|
||||||
|
|
Loading…
Reference in New Issue