2013-04-03 4 views
8

私はNetty 4を習得するための練習として複数のフィードを同時に(1kまで)取り出すためにHTTPクライアントを作成しようとしてきました。Netty 4におけるバッファの所有権:バッファのライフサイクルはどのように管理されますか?

私の質問はどこか新しいByteBufインフラストラクチャは機能しますか?誰が彼らを「所有しているか」、彼らはどのように共有されていますか? ChannelPipeline内のすべてのChannelHandlerには独自のByteBufがありますか?困惑ここ

は私を残し例である:私はMSGでBufUtil.retainを呼び出さない場合

public class MyFilter extends MessageToMessageDecoder<HttpObject> { 

    @Override 
    protected Object decode(ChannelHandlerContext ctx, HttpObject msg) throws Exception { 
     // do some work, but leave msg unchanged 
     BufUtil.retain(msg); // Why do I need to call BufUtil.retain(msg) ??? 
     return msg; 
} 

、:

を私は、HTTPクライアントのパイプラインに次のクラスのインスタンスを追加しましたそれはGCdを取得するようだと私はあらゆる種類の偽のエラーを取得します。

答えて

7

HttpContentReferenceCountedは、保持するバッファのライフサイクルを追跡するために使用します。 ReferenceCountedがインスタンス化されると、refCnt1で始まります。 retain()を呼び出すと、refCntが増加します。 refCntrelease()で減少し、refCnt0になると、基礎リソース(この場合はByteBuf)が破棄されます。

通常、ハンドラは処理が完了したメッセージへの参照を保持する必要はありません。通常、メッセージは処理されたときに別のものにスローされたり変形されたりするためです。したがって、ハンドラを使用してメッセージを処理した後は、release()メソッドを呼び出す必要があります。これはしばしばエラーを起こしやすく、リソースリークを非常に容易にします。

追跡が非常に困難なリークを回避するには、SimpleChannelInboundHandlerを拡張して、処理後にメッセージに自動的にrelease()を呼び出します。

Nettyの参照カウントの詳細については、this wiki pageを参照してください。また、Nettyのバッファーリーク検出メカニズムを使用してバッファーリークのトラブルシューティングを行う方法についての詳細情報も提供します。

+0

こんにちは、ありがとう。パフォーマンスが最も重要な設定では理にかなっています。もしそれがもっと明白になることができれば... – laczoka

+1

@トラスタイン - 私はまた、この参照カウントがすべてユーザーAPIに流出するのに混乱して驚いていました。 API設計では、「最も驚くべきことはしない」と「できるだけシンプルに」する必要があります。たぶんあなたはおなじみのJavaコンストラクトを使うことができます:リソース、try-with-resourcesのように。あるいは単にObjectというメッセージがデフォルトで期待するように振る舞うようにして、高性能で最適化された、より複雑なバージョンを別のインターフェース経由で得るだけです。パフォーマンスは、メモリを漏らしていないと自信を持ってアプリケーションを素早く構築するほど重要ではありません。 – Ryan

+1

@ Ryan、C++のデストラクタのように、Javaのオブジェクトのライフサイクルを明示的に指定する方法があれば、ほとんどの場合参照カウントを導入する必要はありませんでした。しかし、Javaにはこのようなことがないため、参照カウントはバッファを管理する最も効率的な方法です。これはかなりのことではありませんが、残念ながら直接バッファを安全に処理する唯一の方法でした。ところで、Nettyのバッファリークは、比較的簡単に見つかります。http://netty.io/wiki/reference-counted-objects.html#wiki-h2-10 – trustin

関連する問題