2017-12-09 6 views
1

を収集しているものを決定します。連続したループが実行され、MSMQキューのメッセージを待機し、メッセージを処理します。どういうわけかこのプログラムはかなりのメモリリークを持っています。私はすべてのコードを実行し、usingステートメントを使用することができるすべてを行ったが、それでも問題は解決しない。ループの回数が増えるほど、プログラムによって使用されるメモリが高くなります。このメモリは、ガベージコレクタによって再利用されることはありません。私はサービスとして動作VB.NET(.NET 4.5.2)で書かれたコンソールプログラムを持っているGC.Collect()は

私はループの一番下にGC.Collect()を入れてしまった、とメモリのほとんどを解放することができました。しかし、これは悪い習慣であり、問​​題を引き起こす可能性があることを認識しています。 GC.Collect()が取り除く変数を調べる方法があるかどうか疑問に思うので、問題の根本を見つけることができますか?

Do While (True) 
    ' Code to wait for message on a queue 
    ' Code to process message (includes calls to class library) 
    GC.Collect() 
Loop 
+0

メモリリークは、作成したオブジェクトをリリース/廃棄しない可能性が高いためです。そう誰もあなたが呼び出されるGC' 'に関しては間違ってどこ伝えることはできません..あなたは、あなたが – MethodMan

+3

はたぶんGCを実行するために何の理由を見ていない特定のオブジェクトの新しいインスタンスを作成しているところにグローバル検索を行うことができます。実際に問題が発生していますか(メモリ不足の例外のようなものですか)、メモリが増えても実際の問題はないと心配していますか? – Evk

+0

リークが止まるように見えるまでコードをカットすると(ピースごとに)問題を早く解決することができると思います。それから、あなたが最後に削除したものは、犯人でなければなりません。 – mjwills

答えて

2

手動で呼び出したときにガベージコレクタがメモリを解放している場合、メモリがリークしていません。管理されたメモリ環境でのリークは、GCがオブジェクトグラフのどこかで参照されるため解放できないメモリです。

それは、彼らが道あなたのコードはGEN1、GEN2または大きなオブジェクトヒープに推進されているオブジェクトのインスタンスを使用している可能性があります。これらの世代のインスタンスはgen0よりもあまり頻繁に収集されません。 Windowsリソースモニタには、performance counters that can be used to profile the behavior of the managed heapの数が含まれています。私はあなたがgen2に昇格されているオブジェクトを持っているかもしれないと思います。 「Gen 1 Promoted Bytes/Sec」カウンターを追跡すると、これが起きているかどうかについての洞察が得られます。マネージメモリ環境で

は、GCの実行オブジェクトインスタンスが不要になったときにメモリ圧力ではなく、存在しないので、増加メモリ使用の単なる存在は、必ずしも漏れの兆候ではありません。

Collectを取り出した場合、メモリ使用量は常に増加します(キューから処理されるメッセージ数や処理されるメッセージ数など)か、またはsin波のように上下しますか?後者の場合は、GCがそのようにするだけで、漏れはありません。

+0

あなたの質問に答えるには - 私が収集したものを取った場合、ますます多くのメッセージを処理するにつれて、メモリ使用量は常に増加します。プロセスの実行を開始し、キューにメッセージがない場合、使用されるメモリは6.3 MBです。キューに1000個のメッセージを投げれば、処理が始まります。処理が完了するまでにメモリ使用量は2倍になり、処理するキューに新しいメッセージがなくてもそのままになります。 –

+0

@DavidPパフォーマンスカウンターに関するリンク記事から、どの世代に割り当てが行われているかを見ていきたいと思います。プロセスがアイドル状態であるためGCが必ずしも実行されるわけではありません。私はテストシナリオを設定して、GCを稼働させるためにアイテムをキューに連続的に供給します(コレクションはパフォーマンスカウンタで追跡することもできます) – dkackman

関連する問題