トップC# > C#でメモリ使用量を取得する

C#でメモリ使用量を取得する

はじめに

Windowsパソコンの場合、アプリのメモリ使用量はタスクマネージャーで分かる。 いちいち、タスクマネージャーで確認するのが煩わしいので、アプリ画面の片隅に常時表示するか、 ヘルプメニューのクリックで確認できるようにしたい。

これまでのプログラムを真似てもよいが、なるべく簡単な方がいいので、改めてネット検索してみた。

記事[1]に色んな方法が紹介されている。このなかで、一番簡単そうな方法を試そう。

プロセスのメモリ使用量取得方法

ロセスのメモリ使用量取得は、Environment.WorkingSetプロパティ、GCクラス、Processクラス のいずれでもプログラム的には大差がない。

日頃、ガーベージコレクションコレクションが気になっているので、GCクラスを使ってみる。

   long currentSet = GC.GetTotalMemory(true);
   label.Text = string.Format("GC.GetTotalMemory={0}byte", currentSet.ToString("N0"));

地図システムでの使用

地図システムでの使用は次のようにした。毎回、地図画面を書き換えたときに左下の下から2番目に その時点でのメモリ使用量をMB単位(小数点以下切り捨て)で表示する。

public class Map : Panel {

    protected override void OnPaint(PaintEventArgs e) {
        Graphics g = e.Graphics;

        // 省略

        Brush brush = new SolidBrush(Color.Black);
        Font font = new Font("Meiryo UI", 10, FontStyle.Regular);
        //long mem = GC.GetTotalMemory(true)/1024/1024;
        long mem = Environment.WorkingSet/1024/1024;
        g.DrawString(mem+"MB", font, brush, 2, H-35);
        g.DrawString(zoom+"/"+(int)(CX/PX)+"/"+(int)(CY/PX), font, brush, 2, H-20);
    }

}

実画面例を下に示す。これは開発途上のプログラムであり、地図にはまだ表示していないが、 最終的には表示するデータをすでにメモリに読込んでいるため、248MBという大きさになっている。

ところが、タスクマネージャーでは 388MB になっている。この大差の原因はまだ分からない。

アプリ起動後、1時間以上たってから確認するとタスクマネージャーでのメモリ使用量は わずか 45MB になっていた。アプリに読込んだ大半のデータは現時点では使っていないため、 PCが主記憶からスワップアウトしたのであろう。

起動直後は純粋にアプリが使う以上のデータがアサインされているのかも知れない。

OnPaintでの GC.GetTotalMemoryの実行は問題があることが分かった。

Environment.WorkingSet の場合、問題はない。数値はタスクマネージャーに近い値となった。 しかし、OnPaintで頻繁に実行するのはパフォーマンス上好ましくない。

リファレンス

[1] C#でメモリ使用量を取得しましょう|メモリ使用量についても紹介