我有一个非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];
}
}
答案 0 :(得分:0)
对不起,我问道。如果我能在不到24小时的时间里自己回答这个问题我就不会那么努力:(
当我正在调试我的测试应用程序(在Eclipse中)时,它会泄漏,泄漏并泄漏并最终崩溃。 如果我在崩溃之前断开调试器,所有泄漏的内存突然再次可用,并且它会停止泄漏。
我不是百分之百确定一个内存分析器在一个连接上工作,这个连接本身会导致我的数据在我的堆上泄漏,这非常有用。
事实上,它可能与有用的相反。如果这个问题可以让别人在同一个人造墙上敲打几个小时,那么它还值得问一下吗?在关闭它之前,是否有人希望对此有所了解?