2016-07-14 27 views
8

Tôi đang sử dụng OkHttp 3, và tôi tiếp tục nhận được rò rỉ cảnh báo kết nối:OkHttp: tránh kết nối bị rò rỉ cảnh báo

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 

Mỗi lần tôi nhận được một ResponseBody, tôi hoặc gọi .string() được cho là đóng dòng đối với tôi, hoặc tôi một cách rõ ràng đóng nó trong một khối finally, theo cách sau:

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

ứng dụng My tận dụng cường độ cao của mạng, nhưng cảnh báo rằng xuất hiện thường xuyên. Tôi chưa bao giờ quan sát thấy bất kỳ vấn đề nào do rò rỉ được cho là này, nhưng tôi vẫn muốn hiểu nếunhững gì Tôi đang làm sai.

Có ai có thể làm sáng tỏ điều này không?

Trả lời

1

Bằng cách nâng cấp lên OkHttp 3.7, Eclipse bắt đầu cảnh báo tôi về rò rỉ tài nguyên tiềm ẩn. Tôi thấy vấn đề của mình là theo phương pháp này tôi đã viết:

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

Tôi giả định rằng bằng cách luôn gọi getResponse(url, client).body().string() luồng sẽ tự động đóng. Tuy nhiên, bất cứ khi nào một phản ứng không thành công, một ngoại lệ sẽ tăng trước khi thực hiện .string(), do đó luồng sẽ vẫn mở.

Thêm gần đúng trong trường hợp phản hồi không thành công đã giải quyết được sự cố.

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

bạn phải đóng cho cơ thể() thử mã dưới đây

ResponseBody body = resp.body(); 
try { 
    ... 
} finally { 
body.close(); 
} 
+1

Nếu bạn đọc câu hỏi của tôi, mà bạn sẽ thấy rằng tôi đã làm chính xác này ... – Alphaaa

+0

theo dõi vấn đề này, bạn sẽ giúp bạn có được trả lời, không có mã đầy đủ vào đó https: // github. com/square/okhttp/issues/2311 –

+0

Cảm ơn bạn đã liên kết, nhưng vấn đề chỉ là vì người đăng không đóng tất cả nội dung cho các câu trả lời không phải 200. Ở đây với khối 'cuối cùng' tôi nên bắt tất cả các trường hợp. – Alphaaa

1

Như đã đề cập trong câu trả lời khác, bạn phải đóng các phản ứng. Một cách tiếp cận hơi sạch sẽ là khai báo ResponseBody trong khối thử, để nó sẽ tự động bị đóng.

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

Đối với một số người có thể hơi đẹp hơn để đóng 'Phản hồi' thay vì trực tiếp' ResponseBody'. Tức là, việc đóng Phản hồi sẽ đóng Phản hồi cơ bản ... cho các trường hợp sử dụng của tôi, việc đóng trả lời hoạt động tốt hơn một chút. –

+0

Tôi không thể sử dụng phương pháp thử-với-tài nguyên, vì phương pháp của tôi cần trả về cá thể 'Response', được đọc bằng phương thức khác nếu thành công (xem câu trả lời của riêng tôi). – Alphaaa

Các vấn đề liên quan