C# service не могу понять, где здесь утечка памяти

296
23 сентября 2017, 20:39

Создал сервис с помощью шаблона, сократил код до минимума, и всё равно за несколько минут сервис уже не 4, а 8 мб занимает и продолжает расти. Вот сам код:

protected override void OnStart(string[] args)
{
    bool close = false;
    bool alreadySend = false;
    bool firstExecute = true;
    int open_counter = 1;
    while (true)
    {
        if (open_counter >= 2147483643)
            open_counter = 1;
        ManagementObjectCollection sList = null;
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_USBHub");
        sList = searcher.Get();
        sList.Dispose();
        searcher.Dispose();
        open_counter++;
        System.Threading.Thread.Sleep(10);
    }
}

На неиспользуемые переменные не обращайте внимание, просто я удалил часть кода, где они используются. Может здесь и нет утечек, а память сбросится сама в определенный момент, но я не уверен.

Answer 1

Вот тут

 ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_USBHub");

Вы создаете обьект.

А вот тут:

searcher.Dispose();

Вы говорите GC, что его можно удалить, а не удаляете его. И делаете это в цикле.

Это же C#, а не С++. Тут за Вас удаляет все сборщик мусора, он сам решит когда пора чистить и, приостановив программу, почистит.

Попробуйте подождать и понаблюдать. Особенно в Visual Studio это хорошо видно. Там прям график есть.

С MSDN:

Этот метод используется для закрытия или освобождения неуправляемых ресурсов, таких как файлы, потоки и дескрипторы, хранящиеся экземпляром класса, реализующего этот интерфейс. Согласно Конвенции этот метод используется для всех задач, связанных с освобождением ресурсов, находящихся в объекте, или подготовкой объекта к повторному использованию.

Answer 2

Об утечке памяти можно говорить только после продолжительного наблюдения и сравнения снэпшотов состояния памяти. Сборщик мусора в CLR достаточно ленив (говоря строгим языком, его поведение недетерменировано), и если у вас на машине достаточно памяти, то собирать мусор он будет редко. Так что запускайте сервис, берите профайлер и делайте снэпшоты каждый час. А потом смотрите, остались ли в живых какие-то объекты, которые по идее должны были уже удалиться, а так же на их количество (наличие некоторого количества таких объектов нормально).

P.S. Ну и да, используйте лучше using:

using (var searcher = new ManagementObjectSearcher("Select * From Win32_USBHub"))
using (var sList = searcher.Get())
{
   ...
}
READ ALSO
Динамический выбор хранилища из UI .net core 2

Динамический выбор хранилища из UI .net core 2

Есть 2 Бд 1 реляцаонная PostgreSql другая документо-ориентированая MongoDbИ есть реализация Интерфейсов для работы с postgreSql и MongoDb

334
Позиция кнопки в scroll view после Instantiate

Позиция кнопки в scroll view после Instantiate

Привет, после выполнения этого кода var Fbutton = (GameObject)Instantiate(ResourcesLoad("FButton"), transform

279
Unity Android C# Отслеживания нажатия

Unity Android C# Отслеживания нажатия

Нужно чтобы при нажатии на экран(в любой точке) выполнялась функцияА один раз, пока не нажмешь снова(то есть как в флепибёрд), у меня же при...

520
Как определить язык текущей ОС?

Как определить язык текущей ОС?

Хочу сделать программу мультиязычнойМне нужно узнать, какой язык в ОС

267