1

Netty には、メモリ コピーを最小限に抑え、メモリ使用量を最適化しようとする 2 つのシナリオがあります。

(1) 非常に大きなフレーム (20 メガバイト) の読み取り。

(2) 非常に小さなフレーム (フレームあたり 50 バイトで 20 メガバイト) を多数読み取り、パイプラインの上位レベルで 1 つのメッセージに再構築します。

最初のシナリオでは、フレームの先頭で長さを取得するため、FrameDecoder を拡張しました。残念ながら、Netty に長さを返す方法がわかりません (フレームが完全かどうかのみを示します)。Netty は複数のフィル バッファー、コピー、および再割り当てのサイクルを実行しているため、必要以上のメモリを使用していると思います。私がここに欠けているものはありますか?または、このシナリオが予想される場合、FrameDecoder を完全に回避する必要がありますか?

2 番目のシナリオでは、現在 ChannelBuffers.wrappedBuffer を使用してラップするすべての小さなフレームのリンク リストを作成していますが (これを ChannelBufferInputStream でラップできます)、予想よりもはるかに多くのメモリを使用しています (おそらく割り当てられた ChannelBuffers に予備のスペースがあるためですか?)。これは Netty ChannelBuffers を使用する正しい方法ですか?

4

2 に答える 2

2
  1. LengthFieldBasedFrameDecoder と呼ばれる特殊なバージョンのフレーム デコーダがあります。メッセージの長さを含むヘッダーがある場合に便利です。オフセットを指定することで、ヘッダーからメッセージの長さを抽出することもできます。

  2. 実際には、ChannelBuffers.wrappedBuffer は受信データのコピーを作成せず、指定されたバッファーから複合バッファーを作成するため、受信したフレーム データはコピーされません。コード内に複合バッファー/カスタム ラッパーを保持していて、無効化するのを忘れた場合、メモリ リークが発生する可能性があります。

これらは私が従う慣習です、

  • 存続期間の長いオブジェクトに直接バッファを割り当て、使用時にスライスします。

  • 複数のバッファを 1 つの大きなバッファに結合/エンコードしたい場合。ChannelBuffers.wrappedBuffer を使用します

  • バッファがあり、そのバッファまたはその一部で何かをしたい場合は、チャネル バッファ インスタンスで slice または slice(0,..) を呼び出してスライスを作成します。

  • チャネル バッファがあり、小さいデータの位置がわかっている場合は、常に getXXX メソッドを使用します

  • 何かを作るために多くの場所で使用されているチャネルバッファがある場合は、常に変更可能にして、使用時にスライスしてください。

注: channelbuffer.slice はデータのコピーを作成しません。新しいリーダーと書き込みインデックスでチャネル バッファーを作成します。

于 2011-11-21T18:27:51.757 に答える
0

最終的に、FrameDecoder の問題を処理する最善の方法は、SimpleChannelUpstreamHandler の上に独自のものを作成することであると思われました。ヘッダーから長さを決定するとすぐに、長さと正確に一致するサイズの ChannelBuffer を作成しました。これにより (他の変更も加えて)、アプリケーションのメモリ パフォーマンスが大幅に向上しました。

于 2012-01-18T17:33:22.413 に答える