Подтвердить что ты не робот

Размер памяти процесса - разные счетчики

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

Я использую:

Process.GetCurrentProcess().PrivateMemorySize64

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

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

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

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

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

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

4b9b3361

Ответ 1

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

GC.GetTotalMemory(true)

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

Process.GetCurrentProcess().PrivateMemorySize64

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

Process.GetCurrentProcess().WorkingSet64

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

Ответ 2

Если вы хотите использовать "Память (частный рабочий набор)", как показано в диспетчере задач Windows Vista, что эквивалентно "Проводнику процессов" "Частные байты 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);
}

Ответ 3

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

http://shsc.info/WindowsMemoryManagement

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

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

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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