OkHttp: избегайте утечки предупреждение соединения
я использую OkHttp 3, и я продолжаю получать предупреждения об утечке соединения:
WARNING: A connection to https://help.helpling.com/ was leaked. Did you forget to close a response body?
Jul 14, 2016 6:57:09 PM okhttp3.ConnectionPool pruneAndGetAllocationCount
каждый раз, когда я получаю ResponseBody
, Я либо вызову .string()
который предположительно закрывает поток для меня, или я явно закрываю его в finally
блок, следующим образом:
ResponseBody responseBody = response.body();
try (Reader responseReader = responseBody.charStream()) {
...
}
finally {
responseBody.close();
}
мое приложение интенсивно использует сеть, и все же это предупреждение появляется часто. Я никогда не наблюдал никаких проблем, вызванных этой предполагаемой утечкой, но я все равно хотел бы понять если и что Я делаю неправильно.
может ли кто-нибудь пролить свет на это?
3 ответов
обновившись до OkHttp 3.7, Eclipse начал предупреждать меня о потенциальных утечках ресурсов. Я нашел свою проблему в этом методе, я написал:
public static Response getResponse(HttpUrl url, OkHttpClient client) throws IOException {
Builder request = new Request.Builder().url(url);
Response response = client.newCall(request.build()).execute();
if (!response.isSuccessful()) {
boolean repeatRequest = handleHttpError(response);
if (repeatRequest)
return getResponse(url, client, etag);
else
throw new IOException(String.format("Cannot get successful response for url %s", url));
}
return response;
}
Я предполагал, что всегда зовет getResponse(url, client).body().string()
поток закроется автоматически. Но всякий раз, когда ответ был неудачным, перед выполнением .string()
, таким образом, поток остается открытым.
добавление явного закрытия в случае неудачного ответа решить проблема.
if (!response.isSuccessful()) {
boolean repeatRequest = handleHttpError(response);
response.close();
}
Как упоминалось в других ответах, вы должны закрыть ответ. Немного более чистым подходом было бы объявить ResponseBody
в блоке try, так что он будет автоматически закрыт.
try(ResponseBody body = ....){
....
}
вы должны закрыть body () попробуйте ниже code
ResponseBody body = resp.body();
try {
...
} finally {
body.close();
}