Skip to content

Improper creation of OkHttpClient in Websocket.java probably causing Out Of Memory exceptions  #81

Closed
@shobhitpuri

Description

@shobhitpuri

Issue:
I have been having issue with 100's of Out of Memory exceptions in my Android app which is using socket.io-client-java library since couple of months and I've been trying a lot to figure out. The library uses engine.io library.

Hypothesis:
After doing some exploration, this is the hypothesis I have. Please feel free to suggest your thoughts or a fix. In Websocket.java file, each time doOpen() is being called, a new instance of OkHttpClient is being initialized as follows:

public void doOpen() {
     // ..... 
     OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
                // turn off timeouts (github.com/socketio/engine.io-client-java/issues/32)
                .connectTimeout(0, TimeUnit.MILLISECONDS)
                .readTimeout(0, TimeUnit.MILLISECONDS)
                .writeTimeout(0, TimeUnit.MILLISECONDS);
    // ...
    final OkHttpClient client = clientBuilder.build();
    // ...
}

Based on a comment by swankjesse at Square, on an issue opened on okhttp regarding the OOM exceptions, he suggested to share the instance of OkHttpClient. Otherwise each time when we are creating a new instance of OkHttpClient, it will hold its own connection pool and thread pool, which is what seems to be happening when calling doOpen() in Websocket.java. An app which closes connection and opens connection multiple times in its workflow is having lot of OOM exceptions (stacktrace same as on square/okhttp#2846). When a mobile app goes in background, one would want to close connection to prevent using resources and then re-open connection when app is visible.

From the okhttp docs:

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.

Solution seems to be fixing it as mentioned in the docs. Feel free to comment if the hypothesis seems wrong.

Thanks

References:

  1. Crashes on OutOfMemoryError, while there are 257 "OkHttp ConnectionPool" threads square/okhttp#2846
  2. https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.html
  3. Socket.io Java client use this library and it is causing OOM's in them. OutOfMemoryError: pthread_create socket.io-client-java#315

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions