匿名可运行和内存泄漏

时间:2015-06-13 03:12:48

标签: java runnable anonymous-class

假设我们在某个静态类中有一个静态方法,它在单独的线程中运行一些操作(有一个runnable)并通过一些监听器返回结果:

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);
            }
        });
    }
}
}

在其他类中我们调用方法getSomeData():

public class SomeOtherClass {
private Object mResult;

public void someMethod(){

   SomeStaticClass.getSomeData(new IDataLoadCompleteListener(){

     @Override
     public void onDataLoadComplete(final Object result) {
        mResult = result;
     }

   });

}

}

所以在这种情况下,我想知道在mExecService中创建的匿名runnable何时可以被垃圾收集?这段代码中是否存在内存泄漏问题?在我看来,这个匿名的runnable将存在很长时间,直到SomeOtherClass或其字段mResult垃圾收集,导致我们在runnable中创建一个对象并在监听器中传递引用,我是对的吗?

2 个答案:

答案 0 :(得分:4)

匿名类内存泄漏的问题是相反的。您创建的IDataLoadCompleteListener具有对外部类实例的隐式引用:在您的情况下为SomeOtherClass。因此,在收集侦听器之前,不能对SomeOtherClass实例进行垃圾回收。但在你的情况下似乎没问题。对于Runnable,它没有这样的问题,因为它是在static方法中创建的。因此,在执行Runnable之后,它将符合GC和匿名侦听器的条件。在您的情况下不会创建内存泄漏。

答案 1 :(得分:1)

挖掘一些java源代码。线程存储在Worker中的私有ThreadPoolExecutor类中。只要没有完成,所有工人都存储在地图中。完成或终止后,它们将从地图中删除。 Worker以及ThreadRunnable的扩展程序都是垃圾邮件,将会被提取。