ChannelFutureでクライアント側のsync()を待たずに、制御されていない量のTextWebSocketFramesを単純なNetty WebSocketエコーサーバー実装(サンプルパッケージにある実装のわずかに変更されたバージョン)に送信すると、サーバーのヒープメモリ使用量が増加します最終的にメモリがなくなるまで指数関数的に。
テストケース:クライアントは、実際のバイトが書き込まれるまで待機しません。また、サーバーが次のテキストフレームを書き込む前に、テキストをクライアントに「エコー」するのを待機しません。
for (int i = 0; i < 10000000; i++) {
ch.write(new TextWebSocketFrame("Message #" + i));
}
yourkitメモリプロファイラーを観察すると(約20.000フレームが書き込まれたテストの15秒後)、BigEndianHeapChannelBufferオブジェクトの数が過度に増加しました。
BigEndianHeapChannelBuffer 284,509 (objects) 9,104,288 (shallow size) (after ~30.000 frames sent within 10 second window)
サーバー側では、主にBigEndianHeapChannelBuffersオブジェクトとCompositeChannelBuffersオブジェクトから大きな山が見られますが、これらのオブジェクトはクリーンアップもガベージコレクションも行われません(参照が保持されているため不可能な場合があります)。これは、(単一の)ワーカースレッドがクライアントからの急速に着信する要求の処理でビジーであるために、クライアントチャネルへのダウンストリームの「エコー」応答を書き込めないことに関係していると思います。
サーバー側でこれ(偶発的なサービス拒否)を防止/抑制する方法はありますか?