내 응용 프로그램이 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 :는 슈퍼 클래스는 다음과 같습니다
AsyncTask를이 모양public abstract class AbstractUraHostConnection {
protected IUraHostConnectionListener listener = null;
public void setListener(IUraHostConnectionListener listener) {
this.listener = listener;
}
public abstract void sendRequest(HttpUriRequest request);
public abstract void cancel();
}
: 있도록
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