okhttp: Retrofit + OkHTTP causes memory leaks in Tomcat

creation of OkHttpClient with ConnectionPool:

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean(name = "closeableOKHTTP")
public OkHttpClient closeableOKHTTP() {
    ConnectionPool pool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
    OkHttpClient client = new OkHttpClient.Builder() //
            .connectTimeout(3, TimeUnit.MINUTES) //
            .followRedirects(true) //
            .readTimeout(3, TimeUnit.MINUTES) //
            .retryOnConnectionFailure(false) //
            .writeTimeout(3, TimeUnit.MINUTES). //
            connectionPool(pool) //
            .build();
    return client;
}

building service:

SocialRemoteService getRemote() {
    Gson gson = new GsonBuilder() //
            .setLenient() //
            .create();
    return new Retrofit.Builder() //
            .baseUrl(API) //
            .client(okHttpClient) //
            .addConverterFactory(GsonConverterFactory.create(gson)) //
            .callbackExecutor(daemonExecutor) //
            .build() //
            .create(SocialRemoteService.class);
}

@PreDestroy
public void destroy() {
    okHttpClient.connectionPool().evictAll();
}

service:

public interface SocialRemoteService {

    @GET("cities")
    public Call<List<SocialCity>> cities(@Query("searchField") String searchField);

}

Tomcat logs on un-deploy: http://pastebin.com/3s091BKh

Is there any way to prevent memory leaks using retrofit and okhttp? okHttpClient.connectionPool().evictAll() even with new ConnectionPool(5, 1, TimeUnit.SECONDS) does not seem to work.

dependencies:

  • okhttp3 - 3.2.0
  • retrofit2 - 2.0.1
  • retrofit2 converter-gson - 2.0.1
  • tomcat8 - Apache Tomcat/8.0.32
  • java8 - 1.8.0_74-b02

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 21 (9 by maintainers)

Most upvoted comments

Restarting JVM as a solution to memory leaks in life-cycle aware application sounds pretty flimsy to me, to be honest. It sounds like I would have to restart my Android every 4-5 apps I started and closed.

We may try to make this work, but code unloading is not an advertised feature of this library

Direct access to thread pools would do the trick. It might look dirty but in some cases (like using okhttp in server-side apps) it would definitely pay off, especially when pools don’t exit asynchronously as fast as they should.

Different http protocols or code unloading doesn’t really bother me at this point. It’s beacuse I’m unable to manually close those pools which leads to keeping class loader in JVM bothers me.

Can anyone open this issue until it is verified?