question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Android OOM upon network disconnect

See original GitHub issue

With grpc-java 1.15.0 on Android I am seeing out of memory issues when network connectivity goes away. isReady() indicates unlimited readiness on the outbound stream for a bidi call until Java runs out of memory.

Here is the relevant code, the complete example is at https://github.com/bubenheimer/grpcsinglestreamingcallflush

StreamDataGrpc.newStub(channel).streamData(
        new ClientResponseObserver<Item, Item>() {
            private int outCounter = 0;
            private int inCounter = 0;

            @Override
            public void beforeStart(
                    final ClientCallStreamObserver<Item> requestStream) {
                requestStream.setOnReadyHandler(() -> {
                    while (requestStream.isReady()) {
                        final Item item = Item.newBuilder()
                                .setValue(Integer.toString(outCounter++)).build();
                        requestStream.onNext(item);
                        if (outCounter == 50_000) {
                            requestStream.onCompleted();
                            break;
                        }
                    }
                });
            }
            @Override
            public void onNext(final Item value) {
                ++inCounter;
            }

            @Override
            public void onError(final Throwable t) {
                Log.w(TAG, t);
            }

            @Override
            public void onCompleted() {
                Log.i(TAG, "Call completed after " + inCounter + " Items");
            }
        });

where channel is more persistently defined as

channel = AndroidChannelBuilder
            // localhost server from Android emulator
            .forAddress("10.0.2.2", 8082)
            .usePlaintext()
            .context(getApplicationContext())
            .build();

To trigger the issue I do one complete run of the RPC (50,000 messages upstream & 50,000 messages downstream) with the mobile data network on, then I turn mobile data off and do a second run on the same channel. The second run quickly runs out of memory as grpc-java buffers messages it can’t send. The channel does not see a break in the connection when mobile data switches off.

I expected that isReady() would take care of this problem, but it did not. I have tried different variations, including one where writing to the stream is done from a separate, dedicated thread, with 1ms delays between each write, to not block anything and avoid races, but the outcome was the same.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
ejona86commented, Sep 26, 2018

Oops. I guess I can respond. Thanks, @bubenheimer, that is helpful and agrees with what we were thinking the problem was. The problem can manifest multiple ways, so I’m not concerned about the difference between emulator and actual phone.

0reactions
bubenheimercommented, Sep 19, 2018

@ejona86 and others: I wrote this test in the last days, so not a known regression.

Just to clarify, the code from the logs uses 100,000 messages instead of the 50,000 from what I posted, and it uses OkHttpChannelBuilder, otherwise it’s the same code. The log shows two calls, the first one with mobile data on (“Call finished” on line 22 marks the end), and the second one after I disabled mobile data.

The code runs on the Android emulator (I tried with Android API levels 28 and 23) on my Mac and talks to a simple grpc-java server on the Mac via that 10.0.2.2 IP that identifies the host system to the emulator. The grpc-java server uses Netty and all defaults. The emulator pretends that data goes through a mobile data connection, so it must be doing something special; I don’t know the details, or what buffering & proxying may happen in-between.

I also ran this test on a real Android phone (talking to a remote server I set up), and there the broken connection is instantly seen once I turn mobile data off, so it will refuse to send any messages, no OOM.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[SOLVED] Zoom Meeting Keeps Disconnecting on Android
One of the main causes of Zoom disconnects on Android devices is actually your connection to the Internet. When you have a slow,...
Read more >
How to Fix Mobile Network Disconnected on Android - Saint
How to Fix Mobile Network Disconnected on Android ; 1. Restart Your Device. ; 2. Switch Off the Airplane Mode. ; 3. Insert...
Read more >
Solved: Re: Involuntary disconnection - Zoom Community
Every time I join a Zoom meeting using the app from my Android phone, it disconnects after only a few seconds. It automatically...
Read more >
How To Fix Zoom App Internet Connection Error In Android
Thank You Everyone So Much For Watch My Video On " How To Fix Zoom App Internet Connection Error In Android ". I...
Read more >
How To Fix ZOOM Meeting Call Disconnecting Problem ...
Thank You Everyone So Much For Watch My Video On " How To Fix ZOOM Meeting Call Disconnecting Problem Android & Ios "....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found