18

自分の .Net サーバー プロセスが使用しているメモリの量を調べようとしています (監視とログの目的で)。

私は使用しています:

Process.GetCurrentProcess().PrivateMemorySize64

ただし、Process オブジェクトには、使用されているメモリ領域を読み取ることができるいくつかの異なるプロパティがあります。Pag​​ed、NonPaged、PagedSystem、NonPagedSystem、Private、Virtual、WorkingSet です。

そして、「ピーク」:これは、これらの最後のピークがこれまでに取った最大値を保存するだけだと推測しています。

各プロパティの MSDN 定義を読んでも、あまり役に立ちませんでした。メモリの管理方法 (ページングと仮想に関する限り) に関する私の知識は非常に限られていることを認めなければなりません。

したがって、私の質問は明らかに「どちらを使用する必要がありますか?」であり、答えは「場合による」であることはわかっています。

このプロセスは基本的に、起こっていることのメモリに一連のリストを保持しますが、他のプロセスはそれと通信し、何かを照会します。これが実行されるサーバーが大量の RAM を必要とすることを期待しているので、内部に保持されているリストのサイズと比較して RAM 要件を推定できるように、このデータにクエリを実行しています。

だから...どれを使うべきですか?なぜですか?

4

7 に答える 7

14

GC の使用量を知りたい場合は、次を試してください。

GC.GetTotalMemory(true)

プロセスが Windows から何を使用しているか (タスク マネージャーの [VM サイズ] 列) を知りたい場合は、次を試してください。

Process.GetCurrentProcess().PrivateMemorySize64

プロセスが(ページファイルではなく)RAMにあるものを知りたい場合(TaskManagerのMem Usage列)、次を試してください。

Process.GetCurrentProcess().WorkingSet64

さまざまな種類のメモリの詳細については、こちらを参照してください。

于 2008-08-27T20:23:11.090 に答える
8

OK、私はグーグルを通してラースが言及したのと同じページを見つけました、そしてそれは記憶がどのように機能するかをよく知らない人々(私のように)にとって素晴らしい説明だと思います。

http://shsc.info/WindowsMemoryManagement

私の短い結論は次のとおりです。

  • PrivateBytes=プロセスがデータの保存を要求したメモリ。一部はディスクにページングされているかどうかはわかりません。これが私が探していた情報です。

  • 仮想バイト=プライベートバイトに加えて、ロードされたDLLなどのために他のプロセスと共有されるスペース。

  • ワーキングセット=ディスクにページングされていないプロセスのすべてのメモリの部分。したがって、ディスクにページングされる量は(Virtual-Working Set)である必要があります。

助けてくれてありがとう!

于 2008-08-27T20:37:20.027 に答える
5

プロセスエクスプローラーの「WSプライベートバイト」に相当するWindowsVistaタスクマネージャーに表示される「メモリ(プライベートワーキングセット)」を使用する場合のコードは次のとおりです。おそらく、リアルタイム統計のスレッド/バックグラウンドタスクでこの無限ループをスローするのが最善です。

using System.Threading;
using System.Diagnostics;

//namespace...class...method

Process thisProc = Process.GetCurrentProcess();
PerformanceCounter PC = new PerformanceCounter();

PC.CategoryName = "Process";
PC.CounterName = "Working Set - Private";
PC.InstanceName = thisProc.ProcessName;

while (true)
{
 String privMemory = (PC.NextValue()/1000).ToString()+"KB (Private Bytes)";
 //Do something with string privMemory

 Thread.Sleep(1000);
}
于 2008-11-14T08:13:55.023 に答える
3

タスク マネージャーが提供する価値を得るには、上記の Mike Regan のソリューションに脱帽です。ただし、1 つの変更: そうではありません: perfCounter.NextValue()/1000;しかし perfCounter.NextValue()/1024;(つまり、実際のキロバイト)。これにより、タスク マネージャーに表示される正確な値が得られます。

以下は、WPF または WinForms アプリ (この場合は単にタイトル) で「メモリ使用量」(与えられたタスク マネージャー) を簡単な方法で表示するための完全なソリューションです。新しい Window コンストラクター内でこのメソッドを呼び出すだけです。

    private void DisplayMemoryUsageInTitleAsync()
    {
        origWindowTitle = this.Title; // set WinForms or WPF Window Title to field
        BackgroundWorker wrkr = new BackgroundWorker();
        wrkr.WorkerReportsProgress = true;

        wrkr.DoWork += (object sender, DoWorkEventArgs e) => {
            Process currProcess = Process.GetCurrentProcess();
            PerformanceCounter perfCntr = new PerformanceCounter();
            perfCntr.CategoryName = "Process";
            perfCntr.CounterName = "Working Set - Private";
            perfCntr.InstanceName = currProcess.ProcessName;

            while (true)
            {
                int value = (int)perfCntr.NextValue() / 1024;
                string privateMemoryStr = value.ToString("n0") + "KB [Private Bytes]";
                wrkr.ReportProgress(0, privateMemoryStr);
                Thread.Sleep(1000);
            }
        };

        wrkr.ProgressChanged += (object sender, ProgressChangedEventArgs e) => {
            string val = e.UserState as string;
            if (!string.IsNullOrEmpty(val))
                this.Title = string.Format(@"{0}   ({1})", origWindowTitle, val);
        };

        wrkr.RunWorkerAsync();
    }`
于 2012-02-10T06:24:33.670 に答える
0

ワーキングセットは使用するのに適したプロパティではありません。私が収集したものから、プロセスが触れることができるすべてのものが含まれ、複数のプロセスによって共有されているライブラリも含まれているため、そのカウンターで二重にカウントされたバイトが表示されます。プライベートメモリは、見るのにはるかに優れたカウンターです。

于 2008-08-27T20:28:23.760 に答える
0

ページフォールトが発生する頻度も監視することをお勧めします。ページフォールトは、物理メモリからスワップ ファイルに移動されたデータにアクセスしようとすると発生し、システムはこのデータにアクセスする前にディスクからページを読み取る必要があります。

于 2008-08-27T20:43:45.550 に答える