Размер памяти процесса - разные счетчики
Я пытаюсь выяснить, сколько памяти использует мой собственный .Net-сервер (для мониторинга и ведения журнала).
Я использую:
Process.GetCurrentProcess().PrivateMemorySize64
Однако объект Process имеет несколько разных свойств, которые позволяют мне читать используемое пространство памяти:
Paged, NonPaged, PagedSystem, NonPagedSystem, Private, Virtual, WorkSet
а затем "пики": я предполагаю, что просто сохраняю максимальные значения, которые они использовали в последнее время.
Чтение через определение MSDN каждого свойства не оказалось для меня слишком полезным. Я должен признать, что мои знания относительно управления памятью (в том, что касается пейджинга и виртуального) очень ограничены.
Итак, мой вопрос, очевидно, "какой я должен использовать?", и я знаю, что ответ "это зависит".
Этот процесс будет в основном содержать кучу списков в памяти о вещах, которые происходят, в то время как другие процессы общаются с ним и запрашивают его для других. Я ожидаю, что сервер, на котором это будет работать, потребует много оперативной памяти, и поэтому я время от времени запрашиваю эти данные, чтобы иметь возможность оценивать требования к ОЗУ по сравнению с размерами списков, которые он хранит внутри.
Итак... Какую пользу я должен использовать и почему?
Ответы
Ответ 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
Я бы предложил также следить за тем, как часто происходят ошибки страницы. Ошибка страницы происходит, когда вы пытаетесь получить доступ к некоторым данным, перенесенным из физической памяти, для обмена файлами, и система должна прочитать страницу с диска, прежде чем вы сможете получить доступ к этим данным.