Я хотел бы отобразить некоторую статистику памяти (рабочий набор, GC и т.д.) на веб-странице с помощью счетчиков производительности .NET/Process. К сожалению, если на этом сервере есть несколько пулов приложений, они различаются с использованием индекса (# 1, # 2 и т.д.), Но я не знаю, как сопоставить идентификатор процесса (который у меня есть) с этим индексом #xx. Есть ли программный путь (с веб-страницы ASP.NET)?
Получить имя экземпляра счетчика производительности (w3wp # XX) из идентификатора рабочего процесса ASP.NET
Ответ 1
Первый хит в Google:
Появляются несколько счетчиков производительности CLR, которые имеют имена, похожие на "W3wp # 1"
Когда несколько рабочих процессов ASP.NET работают, Common Language Runtime (CLR) будут иметь имена, которые напоминают "W3wp # 1" или "W3sp # 2" и так далее. Это было исправлено в .NET Framework 2.0 для включения счетчик с именем Process ID в .NET. CLR Объект производительности памяти. Эта счетчик отображает идентификатор процесса для пример. Вы можете использовать этот счетчик для определить счетчик производительности CLR который связан с процессом.
Также KB 281884:
По умолчанию Performance Monitor (Perfmon.msc) отображает несколько процессы, имеющие одно и то же имя перечисление процессов в следующим образом:
Процесс № 1 Процесс № 2 Процесс № 3
Монитор производительности также может отображать эти процессы, добавив идентификатор процесса (PID) для имени в следующим образом:
Process_PID
Ответ 2
private static string GetProcessInstanceName(int pid)
{
PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
string[] instances = cat.GetInstanceNames();
foreach (string instance in instances)
{
using (PerformanceCounter cnt = new PerformanceCounter("Process",
"ID Process", instance, true))
{
int val = (int) cnt.RawValue;
if (val == pid)
{
return instance;
}
}
}
throw new Exception("Could not find performance counter " +
"instance name for current process. This is truly strange ...");
}
Ответ 3
Пример chiru не работает в конкретном случае - если у вас есть две версии одной и той же программы, то же имя, а одно не .net, и вы запускаете .net-версию после версии non.net. Версия .Net будет называться applicaion # 1, но когда вы получаете доступ к счетчикам перформанса CLR, используя это имя, имена экземпляров на счетчике имеют имя с номером # 1, поэтому вы получаете сбои.
Ник.
Ответ 4
Несмотря на то, что изменение настроек реестра выглядит довольно просто, к сожалению, большинство из нас не имеют прав на это на сервере (или мы не хотим его трогать!). В этом случае существует небольшое обходное решение. Я писал об этом здесь.
Ответ 5
Я знаю, что ответ был дан раньше, но только для полного рабочего кода я отправляю это решение. Обратите внимание на этот код, основанный на методе, представленном M4N в этой цепочке:
public static long GetProcessPrivateWorkingSet64Size(int process_id)
{
long process_size = 0;
Process process = Process.GetProcessById(process_id);
if (process == null) return process_size;
string instanceName = GetProcessInstanceName(process.Id);
var counter = new PerformanceCounter("Process", "Working Set - Private", instanceName, true);
process_size = Convert.ToInt32(counter.NextValue()) / 1024;
return process_size;
}
public static string GetProcessInstanceName(int process_id)
{
PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
string[] instances = cat.GetInstanceNames();
foreach (string instance in instances)
{
using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process", instance, true))
{
int val = (int)cnt.RawValue;
if (val == process_id)
return instance;
}
}
throw new Exception("Could not find performance counter ");
}
Кроме того, если вы хотите, чтобы общая память нескольких экземпляров одного и того же процесса использовала вышеуказанные методы со следующим:
public static long GetPrivateWorkingSetForAllProcesses(string ProcessName)
{
long totalMem = 0;
Process[] process = Process.GetProcessesByName(ProcessName);
foreach (Process proc in process)
{
long memsize = GetProcessPrivateWorkingSet64Size(proc.Id);
totalMem += memsize;
}
return totalMem;
}