2017-12-10 11 views
1

私はHTTPリクエスト/レスポンスを処理するためにNettyを使用しています。そして、パイプラインにダウンし、次のByteBuf書き込み:ログで公開リソースを理解する

public class MyBusinessLogic 
extends ChannelInboundHandlerAdapter{ 
    public void channelRead(ChannelHandlerContext ctx, Object msg){ 
     ByteBuf bb = ctx.alloc().buffer().writeBytes(//some bytes) 
     ctx.writeAndFlush(bb, ctx.newPromise()) 
     //I did not release bb here 
    } 
} 

を私は持って警告いくつかの類似したに「ByteBuf was garbage collected before it was released」...それに似たもの。

なぜ私たちは自分でByteBufをリリースする必要がありますか?彼らはとにかくゴミ収集されています。 bbをここに公開しないと、私はどのような悪いトラブルに遭遇できますか?

チャンネルの将来のリスナーとしてリリースするバッファを追加するだけですか?

ByteBuf bb = // 
ctx.writeAndFlush(response, ctx.newPromise()) 
.addListener(new ChannelFutureListener(){ 
    public void operationComplete(ChannelFuture f){ 
     buf.release() 
    } 
}); 
+0

関連:https://stackoverflow.com/questions/46326821/severe-leak-bytebuf-release-was-not-called-before-its-garbage-collected-ne https://stackoverflow.com/questions/ 29805270/leak-bytebuf-release-was-before-its-its-garbage-collected-springと呼ばれていました。たぶんこれは:https://logz.io/blog/netty-bytebuf-memory-leak/(私のサイトではなく、ちょうどGoogleの結果から) –

+0

@RCを読む価値があります。私はちょうど答えを見た。私はもう少し詳しく興味深いです。とにかく 'ByteBuf'がガベージコレクションされている場合、何がメモリリークを引き起こす可能性がありますか? –

+0

すべてのByteBufsの1%だけがリーク検出機能を有効にしているので、メモリの99%がデフォルトでリークします:http://netty.io/wiki/reference-counted-objects.html#leak-detection-levels – Ferrybig

答えて

3

http://netty.io/wiki/reference-counted-objects.htmlによれば、網状オブジェクトにそれら(又はそれらの共有リソース)を返すことができるように

網状バージョン4は、特定のオブジェクトのライフサイクルは、その参照カウントで管理されていますプール(またはオブジェクト・アロケータ)を使用しなくなったらすぐに使用できます。ガベージコレクションおよび参照キューは、到達不能のようなリアルタイムの効率的な保証を提供しませんが、参照カウントはわずかな不便を犠牲にして代替メカニズムを提供します。

しかしこれは完全な説明ではありません。 Netty ByteBufは、直接HEAPメモリにアクセスすることもできます。このメモリは、ガベージコレクタがいっぱいになったときに実行されない代わりに例外をスローするような特殊なメモリです。

Nettyがヒープメモリにアクセスしようとする理由は基本的には、ファイルからソケットに、またはソケット1からソケット2にコピーするような "チャンネル"で動作するものであれば、これは、配列を使って同じことをするよりもはるかに優れた性能を持っています。下位レベルは最初にそれをJava配列に変換してから、パケットを送信するときに再び戻す必要があります。

ヒープ(直接)メモリがガベージコレクタと連動するため、作成されるオブジェクトがNetty ByteBufsである特定のケースでは、ヒープメモリがガベージコレクタの呼び出し間でいっぱいになり、ガベージコレクタからの視点からは、メモリは最初は一杯ではなかったからです。ガベージコレクターのこのクォークのおかげで、Nettyは基本的にリリースメソッドを作成して、もはやメモリが不要になったときに直接リリースする必要がありました。

+0

'UnpooledHeapByteBuf'のソースを掘り下げただけです。 'release()'メソッドは、 'UnpooledHeapByteBuf :: freeArray'と呼ばれる、実際には' NO-OP'を呼び出して終了します。 –

+0

Btw、 'ChannelFutureListener'で操作が完了したら、ByteBufを解放するのはどうですか?それは正しい方法ですか、それともいくつかの欠点がありますか? –

関連する問題