Объем памяти процесса - разные счетчики
Я пытаюсь выяснить, сколько памяти использует мой собственный серверный процесс.Net (для целей мониторинга и ведения журнала).
Я использую:
Process.GetCurrentProcess().PrivateMemorySize64
Однако у объекта Process есть несколько различных свойств, которые позволяют мне читать используемое пространство памяти: Paged, NonPaged, PagedSystem, NonPagedSystem, Private, Virtual, WorkingSet
и затем "пики": которые, я предполагаю, просто хранят максимальные значения, которые эти последние когда-либо принимали.
Чтение определения MSDN каждого свойства не оказалось для меня слишком полезным. Я должен признать, что мои знания относительно того, как управляют памятью (насколько пейджинговая и виртуальная), очень ограничены.
Так что мой вопрос, очевидно, "какой из них мне следует использовать?", И я знаю, что ответ "это зависит".
Этот процесс в основном будет содержать несколько списков в памяти происходящих событий, в то время как другие процессы взаимодействуют с ним и запрашивают его. Я ожидаю, что серверу, на котором это будет выполняться, потребуется много оперативной памяти, и поэтому я запрашиваю эти данные с течением времени, чтобы иметь возможность оценить требования к оперативной памяти по сравнению с размерами списков, в которых она хранится.
Итак... Какой я должен использовать и почему?
7 ответов
Если вы хотите узнать, сколько использует GC, попробуйте:
GC.GetTotalMemory(true)
Если вы хотите узнать, что ваш процесс использует в Windows (столбец VM Size в TaskManager), попробуйте:
Process.GetCurrentProcess().PrivateMemorySize64
Если вы хотите узнать, что ваш процесс имеет в ОЗУ (в отличие от файла подкачки) (столбец "Использование памяти" в TaskManager), попробуйте:
Process.GetCurrentProcess().WorkingSet64
Смотрите здесь для более подробного объяснения различных видов памяти.
Хорошо, я нашел через Google ту же страницу, о которой упоминал Ларс, и я считаю, что это отличное объяснение для людей, которые не совсем понимают, как работает память (как я).
http://shsc.info/WindowsMemoryManagement
Мой короткий вывод был:
Частные байты = память, которую мой процесс запросил для хранения данных. Некоторые из них могут быть выгружены на диск или нет. Это информация, которую я искал.
Виртуальные байты = частные байты плюс пространство, совместно используемое другими процессами для загруженных библиотек DLL и т. Д.
Рабочий набор = часть ВСЕЙ памяти моего процесса, которая не была выгружена на диск. Таким образом, количество страниц на диске должно быть (виртуальный - рабочий набор).
Спасибо всем за помощь!
Если вы хотите использовать "Память (частный рабочий набор)", как показано в диспетчере задач 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);
}
Чтобы получить ценность, которую придает диспетчер задач, я предпочитаю решение Майка Ригана, приведенное выше. Однако одно изменение: это не 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();
}`
Это справедливое описание? Я хотел бы поделиться этим со своей командой, поэтому, пожалуйста, дайте мне знать, если это неправильно (или не полностью):
В C# есть несколько способов узнать, сколько памяти использует мой процесс.
- Выделенная память может быть управляемой (с помощью CLR) или неуправляемой.
- Выделенная память может быть виртуальной (храниться на диске) или загружаться (в страницы ОЗУ)
- Выделенная память может быть частной (используемой только процессом) или общей (например, принадлежащей к DLL, на которую ссылаются другие процессы).
Учитывая вышесказанное, вот несколько способов измерить использование памяти в C#:
1) Process.VirtualMemorySize64 (): возвращает всю память, используемую процессом - управляемую или неуправляемую, виртуальную или загруженную, частную или общую.
2) Process.PrivateMemorySize64 (): возвращает всю личную память, используемую процессом - управляемую или неуправляемую, виртуальную или загруженную.
3) Process.WorkingSet64 (): возвращает всю приватную загруженную память, используемую процессом - управляемым или неуправляемым
4) GC.GetTotalMemory(): возвращает объем управляемой памяти, отслеживаемой сборщиком мусора.
Рабочий набор не подходит для использования. Из того, что я понял, он включает в себя все, что может затронуть процесс, даже библиотеки, совместно используемые несколькими процессами, так что вы видите в этом счетчике байты с двойным счетом. Частная память - намного лучший счетчик, чтобы смотреть на.
Я бы посоветовал также отслеживать, как часто происходят сбои страниц. Сбой страницы возникает, когда вы пытаетесь получить доступ к некоторым данным, которые были перемещены из физической памяти в файл подкачки, и система должна прочитать страницу с диска, прежде чем вы сможете получить доступ к этим данным.