'Getting memory leaks with okhttp

When I make a get request to an API, over and over again I see that every request the memory goes up and up until 1gb of ram usage.

closing the response and autoclosable

final OkHttpClient client = new OkHttpClient().newBuilder()
        .connectTimeout(5, TimeUnit.SECONDS)
        .writeTimeout(5, TimeUnit.SECONDS)
        .build();

Request request = new Request.Builder()
        .url("https://api.ipify.org?format=json")
        .addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36")
        .build();

try (Response response = client.newCall(request).execute()) {
    ResponseBody s = response.body();
    assert s != null;
    System.out.println(s.toString());
    s.close();
} catch (IOException e) {
    e.printStackTrace();
}


Solution 1:[1]

TL;DR I think you had the problem because you were creating a new instance OkHttp for every new request.

OkHttp performs best when you create a single OkHttpClient instance and reuse it for all of your HTTP calls. This is because each client holds its own connection pool and thread pools. Reusing connections and threads reduces latency and saves memory. Conversely, creating a client for each request wastes resources on idle pools.

The shutdown isn’t necessary too. The threads and connections that are held will be released automatically if they remain idle. But if you are writing an application that needs to aggressively release unused resources you may do so.

So you can change your code e.g. in a next syncronious way:

private final OkHttpClient client = new OkHttpClient().newBuilder()
    .connectTimeout(5, TimeUnit.SECONDS)
    .writeTimeout(5, TimeUnit.SECONDS)
    .build();

public void run() throws Exception {
  Request request = new Request.Builder()
        .url("https://api.ipify.org?format=json")
        .addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36")
        .build();

  try (Response response = client.newCall(request).execute()) {
    if (!response.isSuccessful()) {
      throw new IOException("Unexpected code " + response);
    }
    System.out.println(response.body().string());
  }

}

Solution 2:[2]

It's an old question, but perhaps it can help someone. You can put the ResponseBody inside try-with-resources.

    final OkHttpClient client = new OkHttpClient().newBuilder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .build();
    
    Request request = new Request.Builder()
            .url("https://api.ipify.org?format=json")
            .addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36")
            .build();
    
    try (Response response = client.newCall(request).execute();
        ResponseBody s = response.body()) {
        System.out.println(s);
    } catch (IOException e) {
        e.printStackTrace();
    }

Solution 3:[3]

You didn't close the connection, use response.close();

            final OkHttpClient client = new OkHttpClient().newBuilder()
                    .connectTimeout(5, TimeUnit.SECONDS)
                    .writeTimeout(5, TimeUnit.SECONDS)
                    .build();

            Request request = new Request.Builder()
                    .url("https://api.ipify.org")
                    .addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36")
                    .build();

            try (Response response = client.newCall(request).execute()) {
                ResponseBody reponseBody = response.body();
                assert reponseBody != null;

                String ip = reponseBody.string();
                System.out.println(ip);
                response.close();
                reponseBody.close();
            } catch (IOException e) {
                e.printStackTrace();
            }```

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Oleg Ushakov
Solution 2 Oleg Ushakov
Solution 3 iFlyinq