【问题标题】:Will this particular use of an anonymous Runnable cause a memory leak?这种对匿名 Runnable 的特殊使用会导致内存泄漏吗?
【发布时间】:2015-06-01 08:03:01
【问题描述】:
private class ProductFragment extends Fragment implements OnGetProductFromDBListener {

    Activity a;

    void onCreate {
         a = getActivity();
        new GetProductFromDB();
    }


    void onGetProductSuccess(Product product) { // This is not called from the main thread because of the implementation of GetProductFromDB
        a.runOnUiThread(new Runnable() {

            void run() {
                // do some UI and Views related stuff
            }

        });
    } 

}

现在,作为匿名类的 Runnable 应该包含对 Fragment 的显式引用,对吧?这会阻止碎片被垃圾收集吗?

我应该担心发生内存泄漏吗?我应该如何防止它?

如果我实例化一个扩展 Runnable 并使其成为静态的类,会有帮助吗?

private static class RunnableTask extends Runnable {


  ProductFragment fragment;

   public RunnableTask (ProductFragment fragment) {
       this.fragment = fragment;
    }

    void run() {

       if(fragment.someBoolean) {
           fragment.doSomething();
       }

    }
}

RunnableTask runnable = new RunnableTask();
a.runOnUiThread(runnable)

【问题讨论】:

  • 只要运行在执行中,引用就会保持

标签: java android multithreading memory-leaks


【解决方案1】:

严格来说,它不一定会导致内存泄漏。但是 - 在线程运行期间,它将持有对外部类的引用(在您的情况下为 ProductFragment)。因此,是否是内存泄漏将取决于线程将运行多长时间,以及它是否最终成为 ProductFragment 类的唯一引用。

您将其分解为静态内部类的建议是一个很好的建议,因为这将删除对外部类的引用,从而消除任何潜在内存泄漏的机会。

但是 - 在您的情况下,鉴于您提议的静态类仍然保留外部类实例的引用,这样做没有任何好处。

【讨论】:

  • 所以与其猜测 run 方法需要多长时间,我可以做一些预防并打破它,对吗?只是为了安全起见
  • 现在我需要从该类中访问片段的可变量。在这种情况下,我将片段传递给该类的构造函数,对吗?
  • 没错。我很确定这本书 Effective Java (强烈推荐) 正是出于这种原因,建议尽可能使用静态内部类。如果您想了解更多详细信息,我建议您查看一下。
  • 啊...这改变了一些事情...如果您需要访问 ProgramFragment 中的内容,那么您最好将其保留原样,因为无论如何您都会保留参考。如果线程不需要这样做,你只会使用静态。
  • 你确定吗?曾经有人告诉我,在静态内部类的构造函数中传递片段是安全的,这样我就可以避免内存泄漏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多