因此我们的应用程序中存在内存泄漏,我们认为它来自WMI调用。
这是我们认为是泄漏的代码:
private ThermalInfo()
{
// ============== Temperature
var mgmtTempScope = new ManagementScope(@"\root\WMI");
var oQuery = new ObjectQuery("select * from MSAcpi_ThermalZoneTemperature");
ManagementObjectSearcher oTempSearch = null;
ManagementObjectCollection collection = null;
try
{
oTempSearch = new ManagementObjectSearcher(mgmtTempScope, oQuery);
collection = oTempSearch.Get();
foreach (var obj in collection)
{
mTemperature = Convert.ToDouble(obj.Properties["CurrentTemperature"].Value) / 10 - 273.2;
mValid = true;
obj.Dispose();
}
}
catch //(Exception ex)
{
// Not supported
mTemperature = 0;
mValid = false;
}
finally
{
if (collection != null)
collection.Dispose();
if (oTempSearch != null)
oTempSearch.Dispose();
FlushMemory();
}
}
这里是FlushMemory():
[DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);
public static void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
}
}
我们的应用程序(它实际上是一项服务)不断发展壮大 - 它唯一要做的就是调用此方法并设置mTemperatur和mValid。随着FlushMemory调用,泄漏停止,我可以整夜运行服务,而不会增加内存。 我现在唯一的问题是服务不再让自己停止。每当我想要停止服务时,它就永远不会停止,我总是不得不用taskkill或任务管理器强制停止它。
有人可以帮帮我吗?另外,我如何避免WMI调用中的泄漏?我已经获得了w8.1所以不应该再成为一个问题,但我想还有......
答案 0 :(得分:0)
我们看到了类似的问题:即使正确使用了using(..){..}和Dispose(),ManagementClass等也会造成大量内存泄漏。 搜索stackoverflow和其他地方,这是一个常见问题。
一次调用 GC.WaitForPendingFinalizers()(属于上面FlushMemory()的一部分),足以修复它(不需要GC.Collect())
尽管我们并不真正认为它是一种解决方案,但这只是一种解决方法。