Let's say we have a some static method in some static class which runs some operations(has a runnable) in separate thread and returns result by some listener:
public class SomeStaticClass {
private static ExecutorService mExecService = Executors.newCachedThreadPool();
........
public interface IDataLoadCompleteListener {
public void onDataLoadComplete(Object result);
}
........
public static void getSomeData(final IDataLoadCompleteListener listener) {
if (listener != null) {
mExecService.execute(new Runnable() {
@Override
public void run() {
........
do something
........
Object result = new Object();
listener.onDataLoadComplete(result);
}
});
}
}
}
And in other class we call method getSomeData():
public class SomeOtherClass {
private Object mResult;
public void someMethod(){
SomeStaticClass.getSomeData(new IDataLoadCompleteListener(){
@Override
public void onDataLoadComplete(final Object result) {
mResult = result;
}
});
}
}
So here in this situation I want to know when anonymous runnable that was created in mExecService become available to be a garbage collected?? There Is some memory leaks issue in this snippet or not?? In my opinion, this anonymous runnable will exist a long time until SomeOtherClass or its field mResult garbage collected, cause we create an object in runnable and passed-by-reference in listener, am I right?
The problem with anonymous classes memory leaks is opposite. The
IDataLoadCompleteListener
you create have an implicit reference to the outer class instance:SomeOtherClass
in your case. ThusSomeOtherClass
instance cannot be garbage collected until the listener is collected. But it seems ok in your case. As forRunnable
, it does not have such problem, because it's created inside thestatic
method. Thus after yourRunnable
is executed, it will be eligible for GC along with anonymous listener. No memory leaks are created in your case.