Объем памяти процесса - разные счетчики - PullRequest
14 голосов
/ 28 августа 2008

Я пытаюсь выяснить, сколько памяти использует мой собственный серверный процесс .Net (для целей мониторинга и ведения журнала).

Я использую:

Process.GetCurrentProcess().PrivateMemorySize64

Однако объект Process имеет несколько различных свойств, которые позволяют мне читать используемое пространство памяти: Paged, NonPaged, PagedSystem, NonPagedSystem, Private, Virtual, WorkingSet

а затем "пики": которые, я предполагаю, просто хранят максимальные значения, которые эти последние когда-либо принимали.

Чтение определения MSDN каждого свойства не оказалось слишком полезным для меня. Я должен признать, что мои знания относительно того, как управляется память (насколько это касается пейджинговой и виртуальной), очень ограничены.

Итак, мой вопрос, очевидно, «какой из них мне следует использовать?», И я знаю, что ответ «это зависит».

Этот процесс будет в основном хранить несколько списков в памяти происходящих событий, в то время как другие процессы связываются с ним и запрашивают его. Я ожидаю, что серверу, на котором это будет выполняться, потребуется много оперативной памяти, и поэтому я запрашиваю эти данные с течением времени, чтобы иметь возможность оценить требования к оперативной памяти по сравнению с размерами списков, в которых она хранится.

Итак ... Какой я должен использовать и почему?

Ответы [ 7 ]

14 голосов
/ 28 августа 2008

Если вы хотите узнать, сколько GC использует, попробуйте:

GC.GetTotalMemory(true)

Если вы хотите узнать, что ваш процесс использует в Windows (столбец «Размер виртуальной машины» в TaskManager), попробуйте:

Process.GetCurrentProcess().PrivateMemorySize64

Если вы хотите узнать, что ваш процесс имеет в ОЗУ (в отличие от файла подкачки) (столбец «Использование памяти» в TaskManager), попробуйте:

Process.GetCurrentProcess().WorkingSet64

См. здесь для более подробного объяснения различных видов памяти.

6 голосов
/ 28 августа 2008

Хорошо, я нашел через Google ту же страницу, о которой упоминал Ларс, и я считаю, что это отличное объяснение для людей, которые не совсем понимают, как работает память (как я).

http://shsc.info/WindowsMemoryManagement

Мой короткий вывод был:

  • Private Bytes = Память, которую мой процесс запросил для хранения данных. Некоторые из них могут быть выгружены на диск или нет. Это информация, которую я искал.

  • Виртуальные байты = Частные байты плюс пространство, совместно используемое другими процессами для загруженных библиотек DLL и т. Д.

  • Рабочий набор = Часть ВСЕЙ памяти моего процесса, которая не была выгружена на диск. Таким образом, количество страниц на диске должно быть (Виртуальный - рабочий набор).

Спасибо всем за помощь!

5 голосов
/ 14 ноября 2008

Если вы хотите использовать «Память (частный рабочий набор)», как показано в диспетчере задач Windows Vista, который является эквивалентом Process Explorer «Частные байты WS», вот код. Вероятно, лучше всего запустить этот бесконечный цикл в потоковой / фоновой задаче для статистики в реальном времени.

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);
}
2 голосов
/ 10 февраля 2012

Чтобы получить значение, которое дает диспетчер задач, я предпочитаю решение Майка Ригана, приведенное выше. Однако одно изменение: это не: 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();
    }`
0 голосов
/ 14 ноября 2018

Это справедливое описание? Я хотел бы поделиться этим со своей командой, поэтому, пожалуйста, дайте мне знать, если это неправильно (или не полностью):

В C # есть несколько способов узнать, сколько памяти использует мой процесс.

  • Выделенная память может быть управляемой (с помощью CLR) или неуправляемой.
  • Выделенная память может быть виртуальной (храниться на диске) или загружаться (в страницы ОЗУ)
  • Выделенная память может быть частной (используемой только процессом) или общей (например, принадлежащей к DLL, на которую ссылаются другие процессы).

Учитывая вышесказанное, вот несколько способов измерить использование памяти в C #:

1) Process.VirtualMemorySize64 (): возвращает всю память, используемую процессом - управляемую или неуправляемую, виртуальную или загруженную, частную или общую.

2) Process.PrivateMemorySize64 (): возвращает всю личную память, используемую процессом - управляемую или неуправляемую, виртуальную или загруженную.

3) Process.WorkingSet64 (): возвращает всю приватную загруженную память, используемую процессом - управляемым или неуправляемым

4) GC.GetTotalMemory (): возвращает объем управляемой памяти, отслеживаемой сборщиком мусора.

0 голосов
/ 28 августа 2008

Я бы посоветовал также отслеживать, как часто происходят сбои страниц. Сбой страницы возникает, когда вы пытаетесь получить доступ к некоторым данным, которые были перемещены из физической памяти в файл подкачки, и система должна прочитать страницу с диска, прежде чем вы сможете получить доступ к этим данным.

0 голосов
/ 28 августа 2008

Рабочий набор не подходит для использования. Из того, что я понял, он включает в себя все, что может затронуть процесс, даже библиотеки, совместно используемые несколькими процессами, так что вы видите в этом счетчике байты с двойным счетом. Личная память - намного лучший счетчик.

...