Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

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

#c_sharp #net #windows #service #wmi


Создал сервис с помощью шаблона, сократил код до минимума, и всё равно за несколько
минут сервис уже не 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);
    }
}


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


Ответы

Ответ 1



Вот тут ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_USBHub"); Вы создаете обьект. А вот тут: searcher.Dispose(); Вы говорите GC, что его можно удалить, а не удаляете его. И делаете это в цикле. Это же C#, а не С++. Тут за Вас удаляет все сборщик мусора, он сам решит когда пора чистить и, приостановив программу, почистит. Попробуйте подождать и понаблюдать. Особенно в Visual Studio это хорошо видно. Там прям график есть. С MSDN: Этот метод используется для закрытия или освобождения неуправляемых ресурсов, таких как файлы, потоки и дескрипторы, хранящиеся экземпляром класса, реализующего этот интерфейс. Согласно Конвенции этот метод используется для всех задач, связанных с освобождением ресурсов, находящихся в объекте, или подготовкой объекта к повторному использованию.

Ответ 2



Об утечке памяти можно говорить только после продолжительного наблюдения и сравнения снэпшотов состояния памяти. Сборщик мусора в CLR достаточно ленив (говоря строгим языком, его поведение недетерменировано), и если у вас на машине достаточно памяти, то собирать мусор он будет редко. Так что запускайте сервис, берите профайлер и делайте снэпшоты каждый час. А потом смотрите, остались ли в живых какие-то объекты, которые по идее должны были уже удалиться, а так же на их количество (наличие некоторого количества таких объектов нормально). P.S. Ну и да, используйте лучше using: using (var searcher = new ManagementObjectSearcher("Select * From Win32_USBHub")) using (var sList = searcher.Get()) { ... }

Комментариев нет:

Отправить комментарий