开发者

Are performance counters the right tool for my job? If so, how do I use them?

开发者 https://www.devze.com 2022-12-22 14:47 出处:网络
I\'ve been asked how to find out how much memory and CPU my program is using, and I\'ve been referred to Performance Counters.However, when I look at the documentation it starts off by telling me abou

I've been asked how to find out how much memory and CPU my program is using, and I've been referred to Performance Counters. However, when I look at the documentation it starts off by telling me about providing consumer data by creating a manifest for my application, and m开发者_开发问答y eyes glaze over. It's nice that such a general-purpose tool is there, I suppose, but all I wanted was a set of functions that would tell me how much memory and CPU my program is using.

Are performance counters the right tool for my job? If so, how do I use them? I really don't want to have to set up anything outside my C# application.

NOTE: I'm not looking for a third-party profiling app, I need to have the memory and CPU data displayed by my app.

UPDATE: I've removed time in functions, as it seemed to be confusing the matter.


You can use perfmon out of the box to monitor CPU, Memory and Disk usage as well as many .NET specific performance counters. perfmon comes with windows.

The eye-glazer is required only if you want to write your own perfmon, or if you want to offer your own performance counters. The latter would be interesting only if your users would need to monitor this value (e.g. you are developing a server application and your users need to make sure there are no more than 10% of connections rejected due to invalid moon phase).

For determining how much time you spend in certain functions, use a profiler.


The Performance Counter API would allow you to monitor the data together with existing performance counters (which might tell you e.g. that function Foo gets very slow every night after 11 because some other process is thrashing the disk), and the monitor can run as a service and produce log files for later analysis.

You must figure out whether these benefits are worth the additional trouble of performance counters, or if you are better off with a logging system.

There are quite some samples out there that might make it easier for you. However, it still pays to understand the architecture and "official" terminology. Typically, MS API's do require a lot of reading and looking for some good wrapper code, that doesn't mean they are always painful.


Assuming a single instance application for CPU usage and Memory (Process Working Set) you could do something like the following:

public static void Main(string[] args)
{
    string processName = Process.GetCurrentProcess().ProcessName;
    int processorCount = Environment.ProcessorCount;

    // Simulate process usage
    for (int i = 0; i < processorCount * 2; i++)
    {
        var t = new Thread(() =>
            {
                while (true) { Console.WriteLine("Busy..."); }
            });

        t.IsBackground = true;
        t.Start();
    }

    var cpu = new PerformanceCounter("Process", "% Processor Time");
    cpu.InstanceName = processName;
    cpu.NextValue();

    var ram = new PerformanceCounter("Process", "Working Set");
    ram.InstanceName = processName;

    float memUsage = (ram.NextValue() / 1024) / 1024;
    Console.WriteLine("Memory Usage: {0}MB", memUsage);

    float cpuUsage = cpu.NextValue() / (float)processorCount;
    Console.WriteLine("CPU Usage: {0}%", cpuUsage);
}

For the CPU usage perf counter the first call to NextValue returns 0 so only the second call is used to display the value. The reported usage is the sum for all machine processors so the average is calculated before being displayed.


For simple information, have a look at these values from within your C# code, then pick what's most relevant to you:

System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime
System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64
System.Diagnostics.Process.GetCurrentProcess().VirtualMemorySize64
System.GC.GetTotalMemory(false)

PrivateMemorySize is the total Private Bytes (managed and unmanaged combined) for your process. GetTotalMemory gives you the total managed memory usage for your app, passing true will force a GC before getting the value.


Performance counters will not tell you how much time your application spends in a function. For that you can use some kind of timer class which you start at the beginning of the function and stop at the end.


how much time it is spending in function

For this you need a profiler (such as the one included in the more advanced editions of Visual Studio). This will give you details of how many times each method is called (with or without functions it calls).

Essential detail for identifying bottlenecks.

CPU

The total process CPU-seconds performance counters (or columns in Task Manager or Process Explorer) will give you this. In practice you might need more detail (kernel vs. user time) that is also available.

memory

This is the difficult part.... "memory" can mean: allocated virtual address space, committed virtual address space, working set, peak working set, private memory, ...

You probably need to spend some time with Windows internals or a similar reference to understand how these are different and what they mean before starting any real analysis.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号