Android grpc-okhttp-3 java.lang.OutOfMemoryError:未能分配8204字节的分配,其中包含3880个可用字节和3KB的内存

Android grpc-okhttp-3 java.lang.OutOfMemoryError:未能分配8204字节的分配,其中包含3880个可用字节和3KB的内存,android,grpc,grpc-java,Android,Grpc,Grpc Java,我正在尝试使用StreamObserver grpc上载一个大小超过300 MB的文件,但出现以下异常。我正在上传512kb的数据块 grpc-okhttp-3 java.lang.OutOfMemoryError:无法分配8204字节的分配,其中包含3880个可用字节和3KB,直到在 Segment.(Segment.java:63)~[na:0.0]at take(SegmentPool.java:48)~[na:0.0]at okio.Buffer.writableSegment(Buff

我正在尝试使用StreamObserver grpc上载一个大小超过300 MB的文件,但出现以下异常。我正在上传512kb的数据块

grpc-okhttp-3 java.lang.OutOfMemoryError:无法分配8204字节的分配,其中包含3880个可用字节和3KB,直到在 Segment.(Segment.java:63)~[na:0.0]at take(SegmentPool.java:48)~[na:0.0]at okio.Buffer.writableSegment(Buffer.java:1211)~[na:0.0]at okio.Buffer.writeByte(Buffer.java:1069)~[na:0.0]at okio.RealBufferedSink.writeByte(RealBufferedSink.java:124)~[na:0.0] 在io.grpc.okhttp.internal.framed.Http2.writeMedium(Http2.java:773) ~(na:0.0)at io.grpc.okhttp.internal.framed.Http2.access$600(Http2.java:47) ~(na:0.0)at io.grpc.okhttp.internal.framed.Http2$Writer.frameHeader(Http2.java:578) ~(na:0.0)at io.grpc.okhttp.internal.framed.Http2$Writer.dataFrame(Http2.java:498) ~(na:0.0)at io.grpc.okhttp.internal.framed.Http2$Writer.data(Http2.java:493) ~(na:0.0)at io.grpc.okhttp.AsyncFrameWriter$9.doRun(AsyncFrameWriter.java:148) ~(na:0.0)at io.grpc.okhttp.AsyncFrameWriter$WriteRunnable.run(AsyncFrameWriter.java:220) ~(na:0.0)at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) ~(na:0.0)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) ~(na:0.0)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) ~[na:0.0]在java.lang.Thread.run(Thread.java:761)~[na:0.0]

BufferedInputStream bInputStream=new BufferedInputStream(new FileInputStream(file));
试一试{
int bufferSize=512;//512k
字节[]缓冲区=新字节[bufferSize];
long size=0,originalSize=file.length();
整块;
做{
chunk=bInputStream.read(缓冲区);
大小+=块;
如果(块>0){
ByteString ByteString=null;
if(块<512){
字节[]剩余=Arrays.copyOfRange(缓冲区,0,块);
byteString=byteString.copyFrom(剩余);
}否则{
byteString=byteString.copyFrom(缓冲区);
}
putRequestStreamObserver.onNext(FileUploadRequest.newBuilder()
.setFileChunk(FileChunk.newBuilder()
.setChunk(byteString)
.build())
.build());
logger.info(“新块!”);

我的清单中有
android:hardwareAccelerated=“false”
android:largeHeap=“true”

由于
StreamObserver
API是异步的,它可以在消息发送之前返回。如果发送太快,它们将在本地缓冲


您需要观察流量控制/背压。您应该创建一个
ClientResponseObserver
以提供
ClientCallStreamObserver
并在
beforeStart()
内调用
setOnReadyHandler()
。然后您需要观察
isReady()
并避免在其变为
false
时发送。请参阅;您可以忽略
disableAutoInboundFlowControl()
/
请求()
parties;即用于接收,而不是发送。

由于
StreamObserver
API是异步的,它可以在消息发送之前返回。如果发送太快,它们将在本地缓冲

您需要观察流量控制/背压。您应该创建一个
ClientResponseObserver
以提供
ClientCallStreamObserver
并在
beforeStart()
内调用
setOnReadyHandler()
。然后您需要观察
isReady()
并避免在其变为
false
时发送。请参阅;您可以忽略
disableAutoInboundFlowControl()
/
请求()
片段;即用于接收而不是发送

BufferedInputStream bInputStream = new BufferedInputStream(new FileInputStream(file));

try {

int bufferSize = 512; // 512k
byte[] buffer = new byte[bufferSize];
long size = 0, originalSize = file.length();
int chunk;
do {
chunk = bInputStream.read(buffer);
size += chunk;
if (chunk > 0) {
ByteString byteString = null;
if (chunk < 512) {
byte[] remaining = Arrays.copyOfRange(buffer, 0, chunk);
byteString = ByteString.copyFrom(remaining);
 } else {
byteString = ByteString.copyFrom(buffer);
}
putRequestStreamObserver.onNext(FileUploadRequest.newBuilder()
.setFileChunk(FileChunk.newBuilder()
.setChunk(byteString)
.build())
.build());

logger.info("New Chunk!");