Страницы

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

среда, 5 февраля 2020 г.

Утечка памяти - потоки и серелизаторы (Thread и Serialize)

#c_sharp #serialize #многопоточность #memory


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

Потоки используются класса Thread, серелизаторы DataContractJsonSerializer (с методами
ReadObject и WriteObject - с одним параметром, Type), а в качестве очереди используется
Queue. 
Периодически создаются объекты, которые добавляются в очередь для последующей обработке
конвейерном ещё в одном потоке. Очередь обрабатывается быстро, быстрее чем в неё поступают
данные. 
В приложении имеется утечка памяти (Working Set растет за час примерно мегабайт на
10 - смотрю через Process Explorer v15.22, - а за пару суток набигает до 512 МБайт).
Приложение использует десериализацию в 2-3 потоках каждые 5-15 секунд.

Вопрос: в какую сторону копать - искать утечку памяти в потоках или сериализаторах,
или может даже в очереди (в последнем я очень сомневаюсь) ?    


Ответы

Ответ 1



Копать нужно только в одном направлении. Вот простая, но хорошая методика поиска утечек, которая скорее всего поможет: подбираем методику, которая приводит к утечке памяти (в соответствии с TaskManager или по факту OutOfMemory). В Вашем случае это просто запустить и подождать часок-другой. Скачиваем Memory analysis tool (тут зависит от желания - кто то может потратить штуку денег и купить крутой анализатор, а кто то может скачать простой, написанный на коленке). К примеру этот его 10 дней триала может хватить. Либо этот от МС с описанием. Тут ещё гугл может очень помочь. запустив программу под анализатором, смотрим результат. Обычно, если есть утечка, то каких то определенных объектов в памяти оказывается очень много. В некоторых случаях можно запускать несколько раз подряд с разной длительностью и смотреть на динамику. Если каких то объектов 1000, но кол-во не изменяется - может они просто кешируются. А течь может один объект в минуту, но на 10 мб. И даже через час их будет 60 штук. вычислив объект(ы), количество которых растет, ищем в памяти их жизненный цикл, гуглим, спрашиваем о них на хэшкоде. Поначалу будет казаться сложно - в дампе тысячи объектов. Но потом придет понимание и они не будут замечаться.

Ответ 2



У меня тоже была когда-то похожая проблема. Тоже приложение жрало всю отведенную память, затем, через несколько часов выдавало ошибку: Out of Memory После того, как я посмотрел состояние потоков приложения через монитор ресурсов, то я ахнул! Я допустил фатальную ошибку - не указывал при создании потока его автоудаление по завершению его работы. В итого "висело" порядка 300 ожидающих потоков в одном процессе! И это количество постоянно росло! Быть может, вы просто создаете по одному новому потоку в таймере, например, но его потом не удаляете?

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

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