私のアプリには、GCが取り上げて消去できない多くのThread
インスタンスが蓄積されています。このメモリリークは、長期的にはアプリケーションをクラッシュさせます。スレッドが死んでメモリリークの原因にならないのはなぜですか?
私は、彼らがどこから来た100%わからないんだけど、私は次のようを感じて明確なを持っている問題のコードのようになります。
public class UraHostHttpConnection extends AbstractUraHostConnection {
private Handler uiThreadHandler = new Handler(Looper.getMainLooper());
private Executor taskExecutor = new Executor() {
public void execute(Runnable command) {
new Thread(command).start();
}
};
private ConnectionTask task = null;
@Override
public void sendRequest(final HttpUriRequest request) {
this.task = new ConnectionTask();
this.uiThreadHandler.post(new Runnable() {
public void run() {
task.executeOnExecutor(taskExecutor, request);
}
});
}
@Override
public void cancel() {
if (this.task != null)
this.task.cancel(true);
}
}
このコードは、私はHTTPいくつかを実行することができます並列接続で、デフォルトでAsyncTask
Executor
(これは単なるスレッド化されたキュー)でブロックされません。
AsyncTask
は、実際にはonPostExecute()
の方法に達しており、永遠に実行されるだけではありません。いくつかのメモリダンプを調べた後、私はThread
-AsyncTask
の完了後にオブジェクトが実行を停止しないと思う。
上記のコードでメモリリークが発生する可能性はありますか、それとも他の場所から探すべきですか?
何か助けていただければ幸いです。
編集:sendRequest
は一度しか呼び出されません。上記のサンプルに含まれていないコードの他の部分は、それを確認します。
編集2:スーパークラスは次のようになります。あなたはオーバーコントロールを持つように
private class ConnectionTask extends AsyncTask<HttpUriRequest, Object, Void> {
final byte[] buffer = new byte[2048];
private ByteArrayBuffer receivedDataBuffer = new ByteArrayBuffer(524288);
@Override
protected Void doInBackground(HttpUriRequest... arg0) {
UraHostHttpConnection.taskCounter++;
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("IVU.realtime.app");
try {
// Get response and notify listener
HttpResponse response = httpClient.execute(arg0[0]);
this.publishProgress(response);
// Check status code OK before proceeding
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
int readCount = 0;
// Read one kB of data and hand it over to the listener
while ((readCount = inputStream.read(buffer)) != -1 && !this.isCancelled()) {
this.receivedDataBuffer.append(buffer, 0, readCount);
if (this.receivedDataBuffer.length() >= 524288 - 2048) {
this.publishProgress(receivedDataBuffer.toByteArray());
this.receivedDataBuffer.clear();
}
}
if (this.isCancelled()) {
if (arg0[0] != null && !arg0[0].isAborted()) {
arg0[0].abort();
}
}
}
} catch (IOException e) {
// forward any errors to listener
e.printStackTrace();
this.publishProgress(e);
} finally {
if (httpClient != null)
httpClient.close();
}
return null;
}
@Override
protected void onProgressUpdate(Object... payload) {
// forward response
if (payload[0] instanceof HttpResponse)
listener.onReceiveResponse((HttpResponse) payload[0]);
// forward error
else if (payload[0] instanceof Exception)
listener.onFailWithException((Exception) payload[0]);
// forward data
else if (payload[0] instanceof byte[])
listener.onReceiveData((byte[]) payload[0]);
}
@Override
protected void onPostExecute(Void result) {
listener.onReceiveData(this.receivedDataBuffer.toByteArray());
listener.onFinishLoading();
UraHostHttpConnection.taskCounter--;
Log.d(TAG, "There are " + UraHostHttpConnection.taskCounter + " running ConnectionTasks.");
}
}
本当にわからないあなたのプールのX =サイズすることができますが、このヘルプあなたは? http://www.androiddesignpatterns.com/2013/04/activitys-threads-memory-leaks.html – dumazy
Spookingする可能性のあるAbstractUraHostConnectionのスーパークラスのコンストラクタには何もありませんか?また、ConnectionTaskはどのように見えますか? – ddmps
両方のクラスのコードが追加されました。 – Chris