Android中的双向流导致OOM

时间:2019-04-29 02:32:45

标签: android grpc grpc-java

我已经在Android应用程序中设置了双向流构造,目前正在使用该机制发送大文件块。我遇到的问题是我的应用程序将收到文件请求消息,然后我将以潜在的数百MB的响应GRPC消息响应,这经常导致OOM。伪代码:

public class Myclass implements StreamObserver<CameraRequest>, Closeable {
  ...

  public void onNext(Request req) {
    for (Chunk chunk : getChunks(req))
      this.requestObserver.onNext(builder.setChunk(chunk).build());
  }

  ...
}

是否有一些不错的方法可以根据线路上实际放置的内容(以及可释放的相应内存)来限制对onNext的未完成呼叫的数量? IE仅允许对onNext进行10次调用,然后阻止后续调用,直到基础协议栈成功发送了先前调用的数据?我可以用我的有线协议TCP样式实现完整的e2e确认窗口,但希望其他人正在使用一种更简单的内置技术。

谢谢!

2 个答案:

答案 0 :(得分:0)

requestObserver投射到ClientCallStreamObserver。然后,您可以致电clientCallStreamObserver.isReady()来检查是否应该停止发送。

然后,当RPC准备接收更多消息时,您将需要通知以恢复发送。为此,实现ClientResponseObserver并在clientCallStreamObserver.setOnReadyHandler(Runnable)中调用beforeStart()

将所有内容放在一起,可以得到类似的东西:

public class MyClass implements
    ClientResponseObserver<CameraRequest,CameraResponse> {
  private ClientCallStreamObserver<CameraRequest> requestObserver;
  private Iterable<Chunk> chunks;

  public void beforeStart(ClientCallStreamObserver<CameraRequest> requestObserver) {
    this.requestObserver = requestObserver;
    requestObserver.setOnReadyHandler(MyClass::drain);
  }

  public void onNext(CameraRequest req) {
    // I don't know if this assert valid for your protocol
    assert chunks == null || !chunks.hasNext();
    chunks = getChunks(req);
    drain();
  }

  public void drain() {
    while (requestObserver.isReady() && chunks.hasNext()) {
      Chunk chunk = chunks.next();
      requestObserver.onNext(builder.setChunk(chunk).build());
    }
  }

  ...
}

答案 1 :(得分:0)

您可以查看流控制示例here