2015-06-13 2 views
1

Допустим, у нас есть некоторый статический метод в каком-то статическом классе, который выполняет некоторые операции (имеет работоспособный) в отдельном потоке и возвращает результат какого-то слушатель:Anonymous работоспособная и утечка памяти

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 будет существовать долгое время до тех пор, пока SomeOtherClass или его сборщик мусора mResult не соберется, потому что мы создадим объект в runnable и pass-by-reference в слушателе, правильно?

+0

runnable имеет ссылку на someOtherClass; но не наоборот. – ZhongYu

+0

Как только Runnable завершил свои действия, как его можно достичь? Объекту все равно, где он создан, например объект, созданный в runnable. Все, что имеет значение, - это если объект доступен или нет, а если нет, он имеет право на сбор мусора. –

ответ

4

Проблема с утечками памяти анонимных классов противоположна. Созданные вами IDataLoadCompleteListener имеют неявную ссылку на экземпляр внешнего класса: SomeOtherClass в вашем случае. Таким образом, экземпляр SomeOtherClass не может быть собран с мусором до тех пор, пока слушатель не будет собран. Но в вашем случае это нормально. Что касается Runnable, у него нет такой проблемы, потому что он создается внутри метода static. Таким образом, после выполнения вашего Runnable, он будет иметь право на GC вместе с анонимным слушателем. В вашем случае нет утечек памяти.

+0

за ваш ответ! – whizzzkey

1

Прокопать некоторые из исходных кодов java. Нити хранятся в приватном классе Worker в ThreadPoolExecutor. Все рабочие хранятся на карте, пока они не завершены. По завершении или прекращении действия они удаляются с карты. Worker, и в добавок Thread и Runnable являются мусором, и их поднимут.

+0

Благодарим вас за ответ – whizzzkey

Смежные вопросы