web-dev-qa-db-ja.com

C#Winformsアプリでの合計プロセスメモリ使用量の矛盾したレポート

編集:バウンティの有効期限が切れましたが、コミュニティがそれを誰かに授与する場合は、Raful Chizkiyahuを選択します。


C#のWinformsプログラムの1つでメモリリークが発生しています。リークの原因をよりよく理解するために、そのメモリ使用量を経時的にグラフ化したいと思います。問題は、通常のメモリ診断コマンドのいずれも、タスクマネージャーがそのプロセスの消費メモリとして要求しているものと一致しないことです。これはおそらく、アプリが安全でない/管理されていないコードを使用していることが合計に含まれていないためだと思いました。

そこで、さらに深く掘り下げるために、メモリ使用量をリアルタイムでレポートするタイマーだけを備えた、非常にシンプルな新しいWinformsアプリを作成しました。私は5つのラベルを使用し、それぞれにさまざまな関数を使用しています(ほとんどがここから ここから ):_Environment.WorkingSet_、GC.GetTotalMemory(false)GC.GetTotalMemory(true)Process.GetCurrentProcess().PrivateMemorySize64およびProcess.GetCurrentProcess().WorkingSet64

驚いたことに(そうではないかもしれませんが)、これらの5つの数値をWindows 10タスクマネージャーと一致させることができません。これがスクリーンショットです:

pic

基本的に私が探しているのは、その5.1MBの数値です。 NETフレームワークから隠し番号をこっそり抽出するにはどうすればよいですか?

以下は、Timer Tick関数にあるコードです。

_private void timer1_Tick(object sender, EventArgs e)
{
    //Refresh();
    label1.Text = "Environment.WorkingSet: " +  Environment.WorkingSet ;
    label2.Text = "GC.GetTotalMemory(false): " +    GC.GetTotalMemory(false) ;
    label3.Text = "GC.GetTotalMemory(true): " + GC.GetTotalMemory(true) ;
    Process proc = Process.GetCurrentProcess();
    label4.Text = "proc.PrivateMemorySize64: " +    proc.PrivateMemorySize64 ;
    label5.Text = "proc.WorkingSet64: " +       proc.WorkingSet64 ;
    proc.Dispose();
}
_

明らかなように、Refresh()コマンドを使用して、または使用せずに試してみましたが、役に立ちませんでした。


編集:バウンティの有効期限が切れましたが、コミュニティがそれを誰かに授与する場合は、Raful Chizkiyahuを選択します。

8
Dan W

優れたツールが必要です。TaskManagerは、特定の瞬間におおよそのメモリ使用量のみを提供します。

メモリリークが疑われる場合、実証済みの方法は、アプリケーションのメモリダンプ(スナップショット)を取得することです。

スナップショットは、アプリケーションの起動時とその後の間隔で取得する必要があります。メモリがゆっくりと増加する場合は、各スナップショットの間に少し待つ必要があります。その後、スナップショットを比較できます。このメソッドを使用すると、オブジェクトの割り当て、オブジェクト数、さらにはアンマネージメモリを分析して比較できます。

Microsoftは、Visual Studioに統合されたメモリ使用量ツールのガイドを作成しています 。ほとんどの場合、これはリークの識別に十分です。

統合されたツールが制限されている場合は、この SO質問 とサイドバーにリンクされている他のツールを確認してください。

0
Alexander Pope