Anonymous runnable and memory leak

1.2k views Asked by At

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?

2

There are 2 answers

0
Tagir Valeev On BEST ANSWER

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. Thus SomeOtherClass instance cannot be garbage collected until the listener is collected. But it seems ok in your case. As for Runnable, it does not have such problem, because it's created inside the static method. Thus after your Runnable is executed, it will be eligible for GC along with anonymous listener. No memory leaks are created in your case.

0
twentylemon On

Dug through some of the java source code. The threads are stored in a private Worker class in the ThreadPoolExecutor. All the workers are stored in a map as long as they are not completed. Upon completion or termination, they are removed from the map. The Worker, and by extension the Thread and Runnable are garbage, and will be picked up.