Process.GetProcessesByName (String, String) Przeciek pamięci

Mam fragment kodu, który pobiera listę procesów na zdalnym komputerze za pomocą metody statycznejProcess.GetProcessesByName (String, String), działa na wielu komputerach (kilka tysięcy) i zauważyłem, że jest to przyczyną poważnego wycieku pamięci.

Uruchomiłem profiler pamięci ANTS, który powiedział mi, że większość mojej pamięci jest pobierana przez ciągi, łańcuchy zawierające wartości strage, takie jak „% czasu bezczynności”, „informacje o procesorze” i „błędy pamięci podręcznej / s”. Rozpoznałem te ciągi jako prawdopodobnie część liczników wydajności w programie, problem polega na tym, że w programie nie ma żadnych liczników wydajności.

Przekopanie się głębiej odkryto, że te łańcuchy są przechowywane w hashtables, które są przechowywane przez PerformanceCounterLib, które są przechowywane przez ANOTHER hashtable, który jest przechowywany w wewnętrznym statycznym elemencie klasy PerformanceCounterLib (który sam w sobie jest wewnętrzny).

Kopiąc jeszcze głębiej w dziurę królika, odkryłem, że Process.GetProcesesByName używa PerformanceCounterLib, aby uruchomić listę procesów na odległym komputerze i że dla każdego zdalnego komputera tworzona jest inna instancja PerformanceCounterLib, do której odwołuje się statyczna zmienna wewnętrzna PerformanceCounterLib. Każda z tych instancji utrzymuje, że hashtable ciągów, które odkryłem, zapycha moją pamięć (każda z nich ma 300-700 kb, co oznacza, że ​​zapycha moją stertę dużych obiektów).

Nie znalazłem sposobu na usunięcie tych nieużywanych instancji PerformanceCounterLib, wszystkie są wewnętrzne i użytkownik nie ma do nich dostępu.

Jak mogę rozwiązać problem z pamięcią? To NAPRAWDĘ złe, mój program osiąga 5 GB (limit mojego serwera) w ciągu 24 godzin.

EDYTOWAĆ: dodano fragment kodu (nie testowany), który powinien odtworzyć problem. Dla wyjaśnienia:

/// computerNames is a list of computers that you have access to
public List<string> GetProcessesOnAllComputers(List<string> computerNames)
{
    var result = new List<string>();
    foreach(string compName in computernames)
    {
        Process[] processes = Process.GetProcesses(compName); // Happens with every     method that gets processes on a remote computer
        string processString = processes.Aggregate(new StringBuilder(), (sb,s) => sb.Append(';').Append(s), sb => sb.ToString());
        result.Add(processString);
        foreach (var p in processes)
        {
            p.Close();
            p.Dispose();
        }
        processes = null;
    }
}

questionAnswers(3)

yourAnswerToTheQuestion