2017-10-20 13 views
0

私はサーバーアプリケーションの書き直しを進めており、アプリケーションのメモリ使用量に困惑しています。以前のバージョンはTcpListenerと書かれましたが、新しいバージョンは普通の古いものですSocket。これは主に、パフォーマンスと安定性の理由から、この問題やこの問題の副次的なものです。非同期ソケット高いメモリ使用率と可能なリーク

前述したように、すべては、AcceptAsync,SendAsync、およびReceiveAsyncと大きく非同期です。さらに、AcceptAsyncの最初のキックオフ、次のAcceptAsyncのキューイング、Socketに書き戻すための処理後のコール、切断されたコールのクリーンアップなどのユーティリティタスクにはThreadPool.QueueUserWorkItemを使用します。さらに、私はBeginInvokeEndInvokeで発砲する一連のイベントがあります。

もの切断ならびにデータの可用性のためのメインドライバの検出はReceiveAsyncならびにDisconnectイベントを発生させ、ゼロであるSocketAsyncEventArgs.BytesTransferredする検出上のピークIはAvailabilityNotifierを呼び出すカスタムクラスによって処理されます。

アプリケーションのスループットは良好で、System.Collections.Concurrentオブジェクトの健全な使用のおかげで、ほとんどゼロ(相対的に言えば)のロック競合があります。しかし、それは殺すために執着する捕食者のように記憶に固執する。

私は内部のコレクションがクリアされていることを確認するためにデバッグしました。クライアントソケットはシャットダウンされ、処分されており、読み込みごとに新しいバッファを作成する代わりにバッファプールを利用しています。最終的に1,000接続(100同時実行)と100,000メッセージの送受信を実行するテストアプリケーションを実行すると、サーバープロセスメモリが約800 MBに膨れ上がり、WindowsがTIME_WAITをクリアしてもダウンしません。私はdiposalコードがObjectDisposedExceptionのトンとヌル例外catchのブロックのおかげで発火していることを知っています。ブロックは下のリンクされたgithubで見ることができます。

私は引用符なしですべてここに記事のためにかなり長いのでここにgithub:https://github.com/hoagsie/TcpServerだと言う。 Program.csClientProgram.csは、自分で実行したい場合にも提供されますが、主な操作はNetworkServer.csAvailabilityNotifier.csです。私が実行しているサンプルサーバーには、会話するWCFサービスがありますが、文字通り変更のない標準のWCFプロジェクトです。私はサンプルシナリオに合わせるためにそれを必要としました。

あるレベルで問題があるかどうかもわかりませんが、AnyCPU/x86ではなくx64モードでビルドします。これは主にターゲットサーバー上でのリソース消費機会のためですが、x86またはx64でこの問題に関する動作の違いに気づいていません。

EDIT:

同僚は、Visual Studioでスナップショットツールを指摘しました。私は以前これを見たことがなかったし、それは私が使っていたものとは異なったものを表示していた。これはdotTraceだった。それは意味を成すSocketAsyncEventArgsオブジェクトの周りの割当量を指摘しましたが、彼らは建物と建物を維持しました。メンバーリストをもう一度見て、Disposeメソッドがあることを発見しました。私の問題は消えてしまった。私はそれがIDisposableオブジェクトであることに気付かなかった。

答えて

0

同僚は、Visual Studioのスナップショットツールを指摘しました。私は以前これを見たことがなかったし、それは私が使っていたものとは異なったものを表示していた。これはdotTraceだった。それは意味を成すSocketAsyncEventArgsオブジェクトの周りの割当量を指摘しましたが、彼らは建物と建物を維持しました。メンバーリストをもう一度見て、Disposeメソッドがあることを発見しました。私の問題は消えてしまった。私はそれがIDisposableオブジェクトであることに気付かなかった。

関連する問題