2012-03-09 8 views
2

プロダクション環境でC#.NETサービスを実行しています。このサービスは、クライアントが登録して要求を行うTCPサーバーとして機能します。タスクマネージャーを見ると、約10MB /日が漏れているようです。私はdevに気付いていないようです(たぶんトラフィックやクライアントのアクティビティがはるかに少ないためです)。私は周りの検索では、タスクマネージャーが深刻に間違っていることがありますが、私はどのくらい正確か、どのような状況でTMが間違った情報を表示するのかよく分かりません。.NETプロダクションサービスでメモリリークをターゲットにする

この問題を解決するには、メモリ消費量をより詳細に監視する必要があります。問題は、リリースされたサービスがリリース用にビルドされている本番環境でのみリークが発生するように見えることです。また、プロファイラー/デバッグが付いたVSで直接実行できないサービスなので、TMより正確な問題をどのように正確に突き止めるべきかはわかりません。

どのグループの知恵は、ありがとう、ありがとう。

編集:私はサービスの陰部のバイトのためのperfmonカウンタを追加しました

  • (30メガバイトが出て起動する)
  • タスクマネージャを(7メガバイトはアウト開始します)だけでなく、すべてのヒープ内のCLR MEMメモリ全体が〜37MBであると言いますので、これは意味をなさないと思われます。
  • これの最初の部分は、サービスを1日かけて、もう一度私のカウンタをチェックアウトさせることです。

私のプライベートバイトが大きくなりますが、CLR memが大体静的である場合、これはアンマネージドリークを示します。両方が巨大になると、管理漏れです。

ありがとうございます。

+1

リリースビルドをテスト/ステージングで実行して、リークを再現できるのはなぜですか?これはステップ1です。リークを特定するには、ステップ2(メモリプロファイラを使用)が必要です。 – Oded

+0

私はこれをしました。残念ながら、トラフィックの量は、dev側では、一桁の大きさです。だから、漏れはそれほど明白ではない。 – kmarks2

答えて

4

(少なくともジェットブレーンズのソリューションがあることハンドル)

http://www.jetbrains.com/profiler/

http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

は、他の選択肢があるが、これらは非常に有能であり、あなたは彼らとリモートアプリケーションのメモリをプロファイリングすることができますプロセスがメモリをリークしている場合。プライベートバイトを測定するperfmonでこれを行うことができます http://www.goldstarsoftware.com/papers/CapturingVirtualBytesToALogFile.pdf

グラフが一貫して上昇している場合(たとえば30分)、メモリリークが発生しています。この場合、他のカウンタを使用して、.NETリーク(.NETメモリ)であるかどうかを判断できます。私は、これらのケースのほとんどで、呼び出されているが解放されていないCOMコンポーネントがあることがわかりました。

実際にメモリリークが発生している場合(これは可変メモリ使用ではありません)、しばらくの間実行した後にプロセスがメモリ不足の例外でシャットダウンします。

+1

素晴らしい。私はperfmonで遊んでいたが、それを役に立つように進歩させていなかった。これは長い道のりです。ありがとう。 – kmarks2

+0

プライベートバイトカウンタとCLRオールヒープメモリカウンタを追加しました。過去1時間の間にプライベートは7から8MBに増加しました。 CLRヒープは16〜20MBの間で変動するようです。奇妙なことは、それが純粋なC#プロジェクトだということです。明示的なマーシャリングやCOM interopはありません。私はこれらのことがバックグラウンドで起こっていると思います(すべての.NET TCPはWinSockなので)。 – kmarks2

2

これを監視するには、以下のMemoryProfilerのいずれかが必要です。あなたの最初のタスクが考え出すさ

+1

**生産**システムに対してこれらを実行することをお勧めしますか? – Oded

+1

なぜでしょうか。 「メモリリーク」を伴う「生産システム」よりも優れている – Zuuum

2

は、このガイドに従ってください:http://blogs.msdn.com/b/tess/archive/2008/03/25/net-debugging-demos-lab-7-memory-leak.aspx

それはあなたが、本番でのメモリリークを記述している正確に何を乗り越えます。前述したように、まず、管理対象コードであるか、perfmonとプライベートバイトを使用してリークしているマネージコードかを判断する必要があります。

一般に、ネットワークオブジェクトは、適切に処理されるようにステートメントを使用してラップしていることを確認してください。

私が管理メモリリークに頻繁に使用するワークフローは、テストマシンでサーバを起動し、既知の接続数(たとえば接続数123,456)で起動することです。その後、タスクマネージャーに行き、プロセス名を右クリックして 'create dump'を選択して、メモリースナップショットを作成します。このダンプをWinDBGとSOSで開き、!dumpheap -statコマンドを実行してください。 123,456インスタンスの倍数を持つオブジェクトを探します。これらのオブジェクトはまだメモリ内にあるはずですか?これらのオブジェクトのインスタンス上で!gcrootを実行しないと、なぜメモリに残っているのかがわかります。

2
  1. タスクマネージャを使用してリーク状態のメモリをダンプするには、プロセスを右クリックして[ダンプファイルの作成]を選択します。さらに多くのオプションを提供するProcDumpを使用することもできます。

  2. WinDebugまたはSUSE拡張機能を使用してメモリを検査します。

関連する問題