内存泄漏终结器错误

时间:2015-04-15 15:48:30

标签: android memory-leaks finalizer

我一直在研究内存泄漏并使用内存分析器工具来检查它们。因此,作为一种实践,我有以下代码泄漏活动,因为匿名内部类持有对活动的引用。这是代码:

   public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleOne();
  }

  private void exampleOne() {
    new Thread() {
      @Override
      public void run() {
        while (true) {
          SystemClock.sleep(1000);
        }
      }
    }.start();
  }
}

我在这里有上述泄漏的内存分析器图像(6次旋转):6 Rotations of the activity. enter image description here

很明显,有6个正在运行的线程持有对外部活动的隐式引用,从而阻止它被垃圾回收。

现在,请考虑以下代码:

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleTwo();
  }

  private void exampleTwo() {
    new MyThread().start();
  }

  private static class MyThread extends Thread {
    @Override
    public void run() {
      while (true) {
        SystemClock.sleep(1000);
      }
    }
  }
}

在这里,我已经将类设置为静态,因此没有对外部活动的引用,GC可以自由地回收Activity对象而不会被线程类阻止。

以下是相同的MAT屏幕截图:6 Rotations again.

enter image description here

我对第二组屏幕截图感到困惑,其中有5个终结器引用。我搜索了它,发现JVM一旦将要进行GCed就将对象添加到引用队列中。我预计,尽管会发生这种情况,但这些变化不会在MAT中出现,因为我不认为GC会花费很多时间来释放这些参考资料。即使我使用13次旋转,结果也是相同的,有12个终结器参考。我可能错了,但我认为MAT只显示1个Activity对象,因为其他人必须已经GCed。有关最终化参考队列的任何帮助,以及在垃圾收集过程中继续进行的过程将受到赞赏。感谢。

1 个答案:

答案 0 :(得分:3)

enter image description here

选择Finalizer概述。它提供了有关等待终结器运行的对象数量以及终结器线程的其他相关信息的信息。