PerformanceCounter creation take a LONG time

▼魔方 西西 提交于 2020-01-02 02:34:09

问题


I'm working on a charge balancing system and thus I need to know the charge of each machine. PerformanceCounter seem the way to go, but creating the first one take between 38 and 60 sec. Each subsequent new Counter or 'NextValue' call is nearly instant however.

Here is the code I'm using :

[TestClass]
public class PerfMon
{
    [TestMethod]
    public void SimpleCreationTest()
    {
        Stopwatch Time = new Stopwatch();
        Time.Start();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds);

        // Create

        PerformanceCounter RAM = new PerformanceCounter("Memory", "Available MBytes");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM created");

        PerformanceCounter CPU = new PerformanceCounter("Processor", "% Processor Time", "_Total");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU created");

        PerformanceCounter GC = new PerformanceCounter(".NET CLR Memory", "% Time in GC", "_Global_");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC created");

        // Read

        float Value = RAM.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM value is : " + Value);

        Value = CPU.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU value is : " + Value);

        Value = GC.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC value is : " + Value);
    }
}

Research

PerformanceCounter extremely slow in connecting remote server

Creating a new System.Diagnostics.PerformanceCounter is very slow

I tried using the other constructors and giving a precise 'MachineName' but it doesn't change anything.

Why a call to PerformanceCounter is slow?

http://craigandera.blogspot.fr/2005/06/performancecounter-constructor-horribly_21.html

According to this two threads, the problem seem to be about the fact that performance counters are a shared resource. However I don't understand how I could solve that.

Running Visual Studio in Administrator 'accelerate' the first creation from 38 sec to 26 sec, so it doesn't solve the problem either.


Thanks for your help.


回答1:


I tried your code on my machine and I got >2.5 seconds for the constructor of the PerformanceCounter. I was not able to debug the .NET Source Code (I'm running VS2013 Express Edition, Windows 7 64b) but I did a series of experinets:

  1. I called the default constructor of the PerformanceCounter. It executes instantly.
  2. Using perfmon I checked the networking related activity. I saw nothing peculiar.
  3. I monitored the memory footprint. I saw that when calling the first parametrized constructor I add ~2.5MB to the memory footprint of the code.
  4. Using perfmon I checked if there's a spike in the count of used mutex, semaphores and other synchronization objects. Nothing unusual happened.
  5. I tested the code in various times while different number of processes were active. I saw that there is great variation. Sometimes i get 1.4 seconds, sometimes I get 2.7 sometimes I get 5 seconds.
  6. I already opened a GUI monitoring session and ran the code but I saw no gain.

So I believe that there is no setup problem and the the answer is that PerformanceCounter constructor does complex work that takes a lot of time to execute.

All the events being monitored are software events, that can be tracked by the operating system. So I suppose that when a new PerformanceCounter object is created, the OS has to generate the current state of the machine. That possibly means getting information for all processes, and most of all, storing that information into a readable and fast accessible structure. What I observed is that the more active processes I have, the slower the PerformanceCounter is created. Also the more cores you have, probably the more data you have to collect.

In the last link you sent, there's a comment that seems to validate this theory but I suppose the spinlock part was optimized since 2005. Probably the measure of last resort is to debug the .NET source for constructing the PerformanceCounter. However I think that this is just how it's implemented.

What I would do is creating the PerformanceCounter objects I need during the initialization phase of the application.




回答2:


This is what fixed it for me:

The performance counters setup time in my application dropped from 2:30 minutes to around 20 seconds by ensuring it was being executed as a 64bit process. The interesting is that I had the performance issue only in a Windows 2012 VM. No problems in Windows 10.



来源:https://stackoverflow.com/questions/22297649/performancecounter-creation-take-a-long-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!