2008-09-22 23 views
13

Tôi muốn hiển thị một số số liệu thống kê bộ nhớ (bộ làm việc, GC, v.v.) trên trang web bằng bộ đếm hiệu suất .NET/Process. Thật không may, nếu có nhiều hồ bơi ứng dụng trên máy chủ đó, chúng được phân biệt bằng cách sử dụng chỉ mục (# 1, # 2, v.v.) nhưng tôi không biết cách so khớp ID tiến trình (mà tôi có) với chỉ mụC#xx đó. Có một cách lập trình (từ một trang web ASP.NET)?Nhận tên đối tượng hiệu suất truy cập (w3wp # XX) từ ID quá trình công nhân ASP.NET

+0

Đây là bài đăng trên blog thảo luận chi tiết về tình huống này: http://weblog.west-wind.com/posts/2014/Sep/27/Capturing-Performance-Counter-Data-for-a-Process-by -Xử lý ID. Về cơ bản, bạn cần sử dụng một bộ đếm hiệu năng khác để lấy ra 'tên cá thể' và sau đó chạy bộ đếm tiến trình của bạn với tên đó. –

Trả lời

11

Các hit đầu tiên trên Google:

Multiple CLR performance counters appear that have names that resemble "W3wp#1"

Khi nhiều công nhân ASP.NET xử lý đang chạy, Common Language Runtime quầy (CLR) thực hiện sẽ có tên tương tự như "w3wp # 1 "hoặc " W3sp # 2 "v.v. Điều này đã được khắc phục trong .NET Framework 2.0 để bao gồm bộ đếm có tên Process ID trong đối tượng hiệu suất Bộ nhớ .NET CLR. Bộ đếm này hiển thị ID tiến trình cho một phiên bản . Bạn có thể sử dụng bộ đếm này để xác định bộ đếm hiệu suất CLR được liên kết với một quy trình.

Cũng KB 281884:

Theo mặc định, Performance Monitor (Perfmon.msc) hiển thị nhiều quá trình có cùng tên bởi liệt kê các quá trình trong sau cách:

Quy trình # 1 Quy trình # 2 Quy trình # 3

Màn hình hiệu suất cũng có thể hiển thị các quá trình này bằng cách thêm các quá trình ID (PID) để tên trong sau cách:

Process_PID

+1

Thực ra điều đó không đúng - có vẻ như việc đặt tên là Quy trình, Quy trình # 1, Quy trình số 2. Đó là một trong đó với ra postfix. –

11
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 ..."); 
} 
+0

tôi nghĩ rằng nó là nhanh hơn: Process p = Process.tGetProcessById (pid); string instance = Process.ProcessName; – pistacchio

+0

được sao chép từ http://weblogs.thinktecture.com/ingo/2004/06/getting-the-current-process-your-own-cpu-usage.html –

+0

@pistacchio Không, điều đó mang lại cho bạn giá trị sai nếu có nhiều hơn một trường hợp của quá trình. –

1

Ví dụ bởi Chiru không hoạt động trong một trường hợp cụ thể - khi bạn có hai phiên bản của cùng một chương trình, được đặt tên giống nhau, và một không phải là .net và bạn bắt đầu phiên bản .net sau phiên bản phi-.net. Phiên bản .Net sẽ được đặt tên là applicaion # 1 nhưng khi bạn truy cập vào các bộ đếm perf của CLR bằng tên này, tên cá thể trên bộ đếm có tên withouth là # 1, vì vậy bạn sẽ gặp lỗi.

Nick.

1

Mặc dù việc thay đổi cài đặt đăng ký trông khá dễ dàng, nhưng hầu hết chúng tôi không có quyền thực hiện trên máy chủ (hoặc chúng tôi không muốn chạm vào nó!). Trong trường hợp đó, có một giải pháp nhỏ. Tôi đã viết blog về số này here.

0

Tôi biết nó đã được trả lời trước đó, nhưng chỉ vì lợi ích của mã làm việc hoàn chỉnh, tôi đang đăng giải pháp này.Xin lưu ý mã này dựa trên phương pháp gửi bởi M4N trong chuỗi này:

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 "); 
} 

Ngoài ra, nếu bạn muốn nhận được tổng số ký ức của nhiều trường hợp của cùng một quá trình sử dụng các phương pháp trên với những điều sau một:

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; 
} 
Các vấn đề liên quan