java memory-leaks okhttp3

java - OkHttp: evitar la advertencia de conexión perdida



memory-leaks okhttp3 (2)

Al actualizar a OkHttp 3.7, Eclipse comenzó a avisarme de posibles fugas de recursos. Encontré que mi problema estaba en este método que escribí:

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; }

Asumí que al llamar siempre a getResponse(url, client).body().string() la secuencia se cerraría automáticamente. Pero, cuando una respuesta no tuvo éxito, una excepción aumentaría antes de la ejecución de .string() , por lo tanto, el flujo permanecería abierto.

La adición de un cierre explícito en caso de una respuesta fallida solucionó el problema.

if (!response.isSuccessful()) { boolean repeatRequest = handleHttpError(response); response.close(); }

Estoy usando OkHttp 3, y continúo recibiendo advertencias de conexión filtradas:

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

Cada vez que obtengo un ResponseBody , llamo a .string() que supuestamente cierra el flujo por mí, o lo cierro explícitamente en un bloque final, de la siguiente manera:

ResponseBody responseBody = response.body(); try (Reader responseReader = responseBody.charStream()) { ... } finally { responseBody.close(); }

Mi aplicación hace un uso intensivo de la red y, sin embargo, esa advertencia aparece con frecuencia. Nunca observé ningún problema causado por esta presunta filtración, pero aún me gustaría entender si estoy haciendo algo incorrecto.

¿Alguien podría arrojar algo de luz sobre esto?


Como se mencionó en las otras respuestas, debe cerrar la respuesta. Un enfoque ligeramente más limpio sería declarar el ResponseBody en el bloque try, para que se cierre automáticamente.

try(ResponseBody body = ....){ .... }