HTTP Transfer Encoding Chunked を Netty 4.0 で動作させようとしています。
これまでのところ成功しています。小さなペイロードでうまく機能します。
次に、大きなデータで試してみましたが、ハングし始めました。
私のコードに問題があるか、ByteBuf.copy() にリークがあるのではないかと思います。
他にリークや副作用の原因がないことを確認するために、コードを最小限に減らし、このテストを作成することになりました。完全なコードはこちらです。
基本的にポート8888にwgetで接続すると1GBの0x0が送信されます。
wget http://127.0.0.1:8888 -O /dev/null
ハンドラーは次のとおりです。
protected void channelRead0(ChannelHandlerContext ctx, FullHttpMessage msg) throws Exception {
DefaultHttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
HttpHeaders.setTransferEncodingChunked(response);
response.headers().set(CONTENT_TYPE, "application/octet-stream");
ctx.write(response);
ByteBuf buf = Unpooled.buffer();
int GIGABYTE = (4 * 1024 * 1024); // multiply 256B = 1GB
for (int i = 0; i < GIGABYTE; i++) {
buf.writeBytes(CONTENT_256BYTES_ZEROED);
ctx.writeAndFlush(new DefaultHttpContent(buf.copy()));
buf.clear();
}
ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT).addListener(ChannelFutureListener.CLOSE);
}
私のアプローチに何か問題がありますか?
編集 :
VisualVM では、.xml にメモリ リークがあることがわかりましたChannelOutboundBuffer
。
は Entry[] buffer
成長し続け、addCapacity()
複数回呼び出されます。Entry
配列には、ワイヤに書き込まれる (または書き込まれるべき) バッファのコピーが含まれているようです。
Wiresharkデータが入ってくるのがわかります...
heapdumpへの Dropbox リンクは次のとおりです。