• C# Как освобождать оперативную память завершенных Task'ов?

    @aaaleinik
    в вашем случае большое потребление памяти (а возможно и других ресурсов) связано не с проблемами утилизации инстансов тасок.

    В обычном сценарии, дефолтный TaskSheduler исполняет Task через ThreadPool.
    При инициализации, ThreadPool создает себе небольшое количество рабочих потоков (начальное число равно количеству ядер в сисетме). Далее ThreadPool следит за их использованием, и если видит что текущее количество рабочих потоков не может обслужить все поступающиие задачи, то создает новый рабочий поток.
    Формально, критерий выделения потока следующий: очередь поступивших задач не пуста И время которое прошло с момента взятия задачи из очери на исполнение больше 500мс И утилизация процессора меньше 80%.

    Таким образом, когда вы ставите на выполнение 2000 Task, которые длительно выполняются, то ThreadPool начинает по медленно штамповать потоки. А вот они уже отнюдь не так легковесны как Task.
    С архитектурной точки зрения, эта ситуация неправильная. Нельзя кидать 2000 задачь выполняться одновременно без какой-либо балансировки. Но утечки памяти здесь нет.

    В вашем случае, можно написать кастомный TaskSheduler, который будет ограничивать степень параллелизма задач, которые отдаются в ThreadPool.
    Или можно воспользоваться Parallel.ForEach, которому можно явно указать степень параллелизма.
    Ответ написан
    1 комментарий
  • C# Как освобождать оперативную память завершенных Task'ов?

    GavriKos
    @GavriKos
    В VisualStudio есть неплохой инструмент профилирования - можете посмотреть где течет память.
    А вообще - пока есть переменная, ссылающаяся на экземпляр класса - память освобождена не будет. Из того что вы написали - вам нужно по завершении каждой таски удалять ее из taskList.
    Ответ написан
    1 комментарий