c# - PerformanceCounter 创建需要很长时间

标签 c# performance load-balancing performancecounter shared-resource

我正在研究电荷平衡系统,因此我需要知道每台机器的电荷。 PerformanceCounter 似乎是可行的方法,但创建第一个需要 38 到 60 秒。然而,每个后续的新 Counter 或“NextValue”调用几乎都是即时的。

这是我使用的代码:

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

研究

PerformanceCounter extremely slow in connecting remote server

Creating a new System.Diagnostics.PerformanceCounter is very slow

我尝试使用其他构造函数并提供精确的“MachineName”,但它没有改变任何东西。

Why a call to PerformanceCounter is slow?

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

根据这两个线程,问题似乎与性能计数器是共享资源这一事实有关。但是我不明白我怎么能解决这个问题。

在 Administrator 中运行 Visual Studio 将第一次创建从 38 秒“加速”到 26 秒,因此它也没有解决问题。


感谢您的帮助。

最佳答案

我在我的机器上试过你的代码,PerformanceCounter 的构造函数得到了 >2.5 秒。我无法调试 .NET 源代码(我运行的是 VS2013 Express Edition,Windows 7 64b),但我进行了一系列实验:

  1. 我调用了 PerformanceCounter 的默认构造函数。它立即执行。
  2. 我使用 perfmon 检查了与网络 相关的事件。我没有看到任何异常。
  3. 我监控了内存占用。我看到在调用第一个参数化构造函数时,代码的内存占用量增加了 ~2.5MB。
  4. 我使用 perfmon 检查使用的互斥量、信号量和其他同步对象的计数是否出现峰值。没有发生异常。
  5. 我在不同数量的进程处于事件状态时多次测试了代码。我看到有很大的变化。有时我得到 1.4 秒,有时我得到 2.7 有时我得到 5 秒。
  6. 我已经打开了一个 GUI 监控 session 并运行了代码,但我没有看到任何收获。

所以我相信没有设置问题,答案是PerformanceCounter 构造函数执行复杂的工作,需要花费大量时间来执行

所有被监控的事件都是软件事件,可以被操作系统跟踪。所以我想当创建一个新的 PerformanceCounter 对象时,操作系统必须生成机器的当前状态。这可能意味着获取所有流程的信息,最重要的是,将该信息存储到可读且可快速访问的结构中。我观察到的是,我拥有的进程越活跃,PerformanceCounter 的创建速度就越慢。此外,您拥有的核心越多,可能需要收集的数据就越多。

在您发送的最后一个链接中,有一条评论似乎证实了这一理论,但我认为自旋锁部分自 2005 年以来已经过优化。可能最后的措施是调试 .NET 源代码以构建 PerformanceCounter。但是我认为这就是它的实现方式。

我要做的是在应用程序的初始化阶段创建我需要的 PerformanceCounter 对象。

关于c# - PerformanceCounter 创建需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22297649/

相关文章:

linux - linux内核是否为实时任务执行负载平衡或任务迁移?

c# - Program.cs 中的 System.MissingMethodException

c# - 如何准确测量Azure Web应用程序中的 "data out"?

ruby-on-rails - 在 AWS 上部署我的第一个应用程序

database - 为 postgres 查询设计索引

java - 将 Java 对象设置为 null 还会有什么作用吗?

azure - 在 Azure 预览门户中为现有 VM 创建 Azure 负载均衡器

C#如何在文本框为空时防止按下Tab键

c# - 如何在 WPF ComboBox 中使用 MultiBinding

c# - unity3d - 加速度计灵敏度