2

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 リンクは次のとおりです。

4

1 に答える 1