Java 尝试写入大缓冲区时,SocketChannel.write()抛出OfMemoryError

Java 尝试写入大缓冲区时,SocketChannel.write()抛出OfMemoryError,java,android,nio,android-memory,socketchannel,Java,Android,Nio,Android Memory,Socketchannel,我的代码在运行以下行时抛出OutOfMemoryError: int numBytes=socketChannel.write(\u send\u buffer); 其中,socketChannel是 而\u send\u buffer是 代码通过非阻塞选择器写入操作到达该点,并在\u send\u buffer的容量较大时,在第一次尝试写入时抛出该操作。当\u send\u buffer小于20Mb时,我对代码没有任何问题,但当尝试使用更大的缓冲区(例如>100Mb)进行测试时,它失败了 根

我的代码在运行以下行时抛出OutOfMemoryError:

int numBytes=socketChannel.write(\u send\u buffer);
其中,
socketChannel

\u send\u buffer

代码通过非阻塞选择器写入操作到达该点,并在
\u send\u buffer
的容量较大时,在第一次尝试写入时抛出该操作。当
\u send\u buffer
小于20Mb时,我对代码没有任何问题,但当尝试使用更大的缓冲区(例如>100Mb)进行测试时,它失败了

根据以下文件:

尝试将最多r个字节写入通道,其中r是调用此方法时缓冲区中剩余的字节数,即src.remaining()。 假设写入了长度为n的字节序列,其中0 0 | | | recv_buffer.position()>0){ 如果(比特读取>0){ //Log.v(标记,从“+socketChannel.getRemoteAddress()”读取“+bitsRead+”字节); } //如果尚未通过2字节短的原始头确定头的长度, //尝试确定它,尽管没有gaurantee,但它将有足够的字节。因此它可能 //多次传递此if语句。只有在读取该语句后,才会 //_jsonheader_len具有非零长度; if(this.\u jsonheader\u len==0){ socketReadTimeStart=System.nanoTime(); 进程_protoheader(); } //_jsonheader_len只有在设置正确(设置完成)的情况下才会大于0。 //jsonHeaderRead将为null,直到它填充并转换为缓冲区集合 //JSONobject。 else if(this.jsonHeaderRead==null){ process_jsonheader(); } 否则如果(!msgReadComplete){ 过程内容(选择键); }否则{ Log.e(标记为“比特读取但不知道如何处理它们”); } } } } 私有无效写入(SelectionKey SelectionKey)引发IOException、JSONException{ 如果(!writeBufferVector.isEmpty()){ SocketChannel SocketChannel=(SocketChannel)selectionKey.channel(); Log.v(标记“writeBufferVector包含数据”); if(jsonHeaderWrite==null){ int numBytesToWrite=writeBufferVector.get(0.limit(); //创建包含事件长度(字节)的JSONHeader Log.v(标记,“生成jsonheader”); jsonHeaderWrite=生成jsonheader(numBytesToWrite); byte[]jsonBytes=jsonHeaderWrite.toString().getBytes(StandardCharsets.UTF_8); //将JSONHeader的长度编码为前两个字节,并写入socketChannel int jsonLength=jsonBytes.length; //将protoHeader、JSONheader和插曲字节的长度相加 int totalNumBytesToWrite=Integer.BYTES+jsonLength+numBytesToWrite; //创建编译protoHeader、JsonHeader和Incide的新缓冲区 _发送缓冲区=ByteBuffer.allocate(totalNumBytesToWrite); Log.v(标记“组装发送缓冲区”); //组装所有字节并翻转以准备读取 _send_buffer.putInt(jsonLength); _send_buffer.put(jsonBytes); _send_buffer.put(writeBufferVector.get(0)); _send_buffer.flip(); Log.d(标记“写入服务器…”); //将字节写入socketChannel//todo不应为空,而as应为非阻塞 if(_send_buffer.remaining()>0){ int numBytes=socketChannel.write(_send_buffer);//此处todo内存转储错误! int percentDone=(int)Math.ceil(((双精度)\u send\u buffer.limit()-(双精度)\u send\u buffer.remaining()) /(双精度)_send_buffer.limit())*100); int total=\u send\u buffer.limit()/1000000; //Log.d(标记“Sent”+percentDone+“%of”+total+“Mb到”+socketChannel.getRemoteAddress()); } }否则{ //将字节写入socketChannel if(_send_buffer.remaining()>0){ socketChannel.write(发送缓冲区); } } if(_send_buffer.remaining()==0){ int total=\u send\u buffer.limit()/1000000; 双时间=(System.nanoTime()-socketWriteTimeStart)*10e-10; DecimalFormat df=新的DecimalFormat(); df.setMaximumFractionDigits(2); Log.i(标记为“+df.format(timetake)+”s“,“Sent”+“total+”Mb); //从缓冲区中删除插曲,以免再次写入。 writeBufferVector.remove(0); //清除发送缓冲区 _发送缓冲区。清除(); //设为null,以便捕获初始if语句以编写新的if语句。 jsonHeaderWrite=null; //将套接字设置为在写入完成后读取。 Log.d(标记“从服务器读取…”); int ops=SelectionKey.OP_READ; sc.register(selectionKey.selector(),ops,selectionKey.attachment()); } } } 私有JSONObject generate_jsonheader(int numBytesToWrite)抛出JSONException{ JSONObject jsonHeader=新的JSONObject(); jsonHeader.put(“byteorder”,byteorder.nativeOrder().toString()); jsonHeader.put(“内容长度”,numBytesToWrite); put(“内容类型”、“flatbuffer”)//
2021-04-22 11:52:44.260 11591-11733/jp.oist.abcvlib.serverLearning I/.serverLearnin: Clamp target GC heap from 195MB to 192MB
2021-04-22 11:52:44.260 11591-11733/jp.oist.abcvlib.serverLearning I/.serverLearnin: Alloc concurrent copying GC freed 2508(64KB) AllocSpace objects, 0(0B) LOS objects, 10% free, 171MB/192MB, paused 27us total 12.714ms
2021-04-22 11:52:44.261 11591-11733/jp.oist.abcvlib.serverLearning W/.serverLearnin: Throwing OutOfMemoryError "Failed to allocate a 49915610 byte allocation with 21279560 free bytes and 20MB until OOM, target footprint 201326592, growth limit 201326592" (VmSize 5585608 kB)
2021-04-22 11:52:44.261 11591-11733/jp.oist.abcvlib.serverLearning I/.serverLearnin: Starting a blocking GC Alloc
2021-04-22 11:52:44.261 11591-11733/jp.oist.abcvlib.serverLearning I/.serverLearnin: Starting a blocking GC Alloc