C# WMI导致内存泄漏(在多个线程中运行时)

C# WMI导致内存泄漏(在多个线程中运行时),c#,thread-safety,wmi,C#,Thread Safety,Wmi,我的问题类似于但有线索 我正在编写一个简单的应用程序来监视来自多个服务器的进程和内存信息。但是,存在内存泄漏。我已将问题缩减到以下简单的控制台应用程序 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Management; using System.Threading; namespace ConsoleApplication1 { c

我的问题类似于但有线索

我正在编写一个简单的应用程序来监视来自多个服务器的进程和内存信息。但是,存在内存泄漏。我已将问题缩减到以下简单的控制台应用程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Threading;


namespace ConsoleApplication1
{
    class Program
    {
        public static void dummyQuery(string ip, string query)
        {
            ConnectionOptions connOptions = new ConnectionOptions();
            ManagementScope mgtScope = new ManagementScope(@"\\" + ip + @"\ROOT\CIMV2", connOptions);


            mgtScope.Connect();

            ObjectQuery queryo = new ObjectQuery(query);

            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(mgtScope, queryo))
            {

                using (ManagementObjectCollection moc = searcher.Get())
                {

                }
            }
        }

        static void Main(string[] args)
        {
            Console.ReadKey();
            int times = 10000;
            for (int i = 0; i < times; i++)
            {

                Thread t = new Thread(o => dummyQuery("xxxxxxxxx", @"SELECT WorkingSetSize FROM Win32_Process WHERE name='W3WP.exe'"));
                //t.IsBackground = true;

                t.Start();

                System.Threading.Thread.Sleep(50);
            }
            Console.ReadKey();
            //GC.Collect();
            Console.ReadKey();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用制度管理;
使用系统线程;
命名空间控制台应用程序1
{
班级计划
{
公共静态void dummyQuery(字符串ip,字符串查询)
{
ConnectionOptions connpoptions=新的ConnectionOptions();
ManagementScope mgtScope=新的管理范围(@“\\”+ip+@“\ROOT\CIMV2”,选项);
mgtScope.Connect();
ObjectQuery queryo=新的ObjectQuery(查询);
使用(ManagementObjectSearcher search=新的ManagementObjectSearcher(mgtScope,queryo))
{
使用(ManagementObjectCollection moc=searcher.Get())
{
}
}
}
静态void Main(字符串[]参数)
{
Console.ReadKey();
整数倍=10000;
for(int i=0;idummyQuery(“xxxxxxxxx”,“从Win32_进程中选择WorkingSetSize,其中name='W3WP.exe'));
//t、 IsBackground=true;
t、 Start();
系统.线程.线程.睡眠(50);
}
Console.ReadKey();
//GC.Collect();
Console.ReadKey();
}
}
}
有没有办法安全地从线程运行WMI查询


这是从一个更复杂的wpf应用程序中提取出来的,该应用程序与dummyQuery方法非常相似,可以检查许多服务器的状态。该应用程序以令人不安的速度泄漏与WMI调用相关的内存。此示例看起来没有泄漏内存(Jim Mischel有更好的方法来检查)。我将安装一个探查器,然后再看一看原始应用。

我知道这可能会被视为一个死线程,但在我寻找解决ManagementObjectSearcher内存泄漏问题的方法时,它是搜索列表的第一个

我的应用程序是一个多线程应用程序,在初始化过程中在主线程上调用WMI。然后,应用程序生成了多个线程,其中没有使用WMI。但是,应用程序在作为Windows服务运行时不断泄漏内存(如果作为标准可执行文件运行,则没有问题)


将[MTAThread]属性放在主入口点上解决了问题。

我知道这可能会被视为死线程,但在我寻找解决ManagementObjectSearcher内存泄漏问题的方法时,它是搜索列表的顶部

我的应用程序是一个多线程应用程序,在初始化过程中在主线程上调用WMI。然后,应用程序生成了多个线程,其中没有使用WMI。但是,应用程序在作为Windows服务运行时不断泄漏内存(如果作为标准可执行文件运行,则没有问题)


将[MTAThread]属性放在主入口点上解决了问题。

为什么要调用GC.Collect();手动?你用内存探查器验证内存泄漏了吗?你也试过使用我不明白你怎么能说这是内存泄漏。首先,如果在调用
GC.Collect
之后内存使用量明显减少,则表明GC在调用它之前不需要收集。如果内存使用率没有改变,这可能只是意味着GC“释放”了内存,但就操作系统而言保留了分配/保留的内存
GC.GetTotalMemory(true)
可以更好地了解实际使用了多少内存,但即使这样也不够。如果没有内存分析工具,您所能做的就是胡乱猜测和不知情的猜测。如果您断言存在内存泄漏,请告诉我们您是如何诊断此泄漏的,您使用了哪个内存分析工具,以及结果是什么。我希望您没有使用任务管理器作为分析工具。为什么要调用GC.Collect();手动?你用内存探查器验证内存泄漏了吗?你也试过使用我不明白你怎么能说这是内存泄漏。首先,如果在调用
GC.Collect
之后内存使用量明显减少,则表明GC在调用它之前不需要收集。如果内存使用率没有改变,这可能只是意味着GC“释放”了内存,但就操作系统而言保留了分配/保留的内存
GC.GetTotalMemory(true)
可以更好地了解实际使用了多少内存,但即使这样也不够。如果没有内存分析工具,您所能做的就是胡乱猜测和不知情的猜测。如果您断言存在内存泄漏,请告诉我们您是如何诊断此泄漏的,您使用了哪个内存分析工具,以及结果是什么。我希望您没有使用任务管理器作为分析工具。我无法确认这是否正确。但我想是的。我不能确认这是正确的。但我想是的。