临时线程泄漏它们引用的东西(目标java.lang.thread)

时间:2013-11-19 12:27:11

标签: java android multithreading memory-leaks

我有一个非UI线程的Android应用程序需要响应,但需要偶尔执行长时间运行的任务。为此,我让它生成一个线程来运行任务。该线程接受对象的引用。此对象似乎泄漏。我跑得太快了。

我期待很多人告诉我使用AsyncTask。我觉得AsyncTask比普通的''线程更难以使用,而且我不在这里的UI线程中。我会倾听建议,但如果建议解释为什么,我会很感激!

我编写了一个非常简单的程序来演示这个问题,该程序运行一个线程,每秒使用整数值更新textview。完成后,它会生成一个将整数递增1的线程。该线程也毫无理由地引用了一个名为“BigFatBlob”的对象。它像筛子一样泄漏。我不明白为什么。在程序代码之后,我附上了一个显示泄漏和传入参考的堆的MAT分析的部分屏幕截图。

下面看的功能是“increment()”。如果有人能告诉我为什么我的程序漏了,我会非常感激 - 我在这里有点迷失。

public class MainActivity extends Activity {

  TextView text_;
  int value_;
  boolean ready_;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    text_ = (TextView)findViewById(R.id.textView);
    value_ = 0;
    ready_ = false;
    watcher();
    increment(new BigFatBlob());
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  /** Updates the text view object to show the current value */
  public void updateText() {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        text_.setText("" + value_);
      }
    };
    runOnUiThread(r);
  }

  /** runs forever, checking for new values every second */
  private void watcher() {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        while (true) {
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
          }
          if (pollReady()) {
            updateText();
            increment(new BigFatBlob());
          }
        }
      }
    };
    Thread t = new Thread(r);
    t.start();
  }

  /** runs once - increments the value by 1 and flags "ready" */
  public void increment(final BigFatBlob junk) {
    Runnable r = new Runnable() {
      private BigFatBlob j;

      @Override
      public void run() {
        setJ(junk);
        ++value_;
        setReady(true);
      }

      public BigFatBlob getJ() {
        return j;
      }

      public void setJ(BigFatBlob j) {
        this.j = j;
      }
    };
    Thread t = new Thread(r);
    t.start();
  }

  /** ready is synchronized */
  private synchronized void setReady(boolean state) {
    ready_ = state;
  }

  /** get the ready value and, if it was true, make it false again */
  private synchronized boolean pollReady() {
    if (ready_) {
      ready_ = false;
      return true;
    }
    return false;
  }
}

public class BigFatBlob {

  byte[] blob_;

  public BigFatBlob() {
    blob_ = new byte[1000];
  }
}

image of memory leak trace

1 个答案:

答案 0 :(得分:0)

对不起,我问道。如果我能在不到24小时的时间里自己回答这个问题我就不会那么努力:(

当我正在调试我的测试应用程序(在Eclipse中)时,它会泄漏,泄漏并泄漏并最终崩溃。 如果我在崩溃之前断开调试器,所有泄漏的内存突然再次可用,并且它会停止泄漏。

我不是百分之百确定一个内存分析器在一个连接上工作,这个连接本身会导致我的数据在我的堆上泄漏,这非常有用

事实上,它可能与有用的相反。如果这个问题可以让别人在同一个人造墙上敲打几个小时,那么它还值得问一下吗?在关闭它之前,是否有人希望对此有所了解?