Така че имаме изтичане на памет в нашето приложение и смятаме, че е от 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 Call изтичането спря и можех да изпълнявам услугата цяла нощ без никакво нарастване на паметта. Единственият проблем, който имам сега, е, че услугата вече не позволява да спре. Всеки път, когато искам да спра услугата, тя никога не спира и винаги трябва да я спирам принудително с taskkill или диспечера на задачите.
Може ли някой да ми помогне с това? Освен това как мога да избегна изтичането на WMI повиквания? Имам w8.1, така че вече не би трябвало да има проблем, но предполагам, че има...
FlushMemory
метод. Вземете профайлър на паметта и намерете какво държи паметта. Не насилвайте ненужноGC.Collect
, което е начин да предизвикате проблеми с производителността. Можете да използвате всеки профайлър на паметта. Профайлър на ANTS или дори този, който идва с визуално студио. - person Sriram Sakthivel   schedule 26.03.2015