内存泄漏终结器错误

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

   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活动的旋转。在这里输入图像描述

很显然,有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可以自由回收活动对象而不被线程类阻止。

以下是相同的MAT截图: 6再次旋转。

在这里输入图像描述

我对第二组截图有困惑,其中有5个终结器引用。 我搜索了一下,发现JVM在对象被加入GC之后会将这些对象添加到引用队列中。 我预计,虽然会发生这种情况,但MAT中不会提供这些更改,因为我认为GC不会花费太多时间来释放这些引用。 即使我使用13次旋转,结果也是一样的,有12次终结器参考。 我可能是错的,但我认为MAT只会显示1个Activity对象,因为其他人必须已经被GCed。 任何关于最终化引用队列的帮助,以及在垃圾回收时继续进行的过程,我们将不胜感激。 谢谢。


在这里输入图像描述

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

链接地址: http://www.djcxy.com/p/25623.html

上一篇: Memory leak Finalizer error

下一篇: How can one use a lambda to create a new EventHandler?