Как мне запустить профилировщик памяти в наших тестовых проектах?

#.net #unit-testing #nunit #memory-profiling #ants

#.net #модульное тестирование #nunit #профилирование памяти #муравьи

Вопрос:

Все,

Что-то не так с нашим тестовым проектом, который выдает исключения из ООМ, и я подозреваю, что проблема в нас. Мы каким-то образом храним ссылки, и память никогда не освобождается.

Итак, я хотел бы запустить профилировщик памяти и посмотреть, где это происходит.

Настройка инструмента профилировщика — это простой вопрос указания инструмента на nunit-console.exe и запускаем наш тестовый проект и делаем несколько снимков.

К сожалению, это не работает. Я пробовал как SciTech, так и demoed ANTS, и оба радостно сообщают, что сборка консоли NUnit / appdomain / что угодно не растет. Отлично. Объем процесса в диспетчере задач неуклонно увеличивается до 450 МБ, но профилировщики памяти сообщают, что он вообще не увеличился.

Отлично.

Я погуглил и увидел несколько (специфичных для инструмента) упрощенных инструкций о том, как работать с проектами модульного тестирования. Я пробовал эти вещи, и они не сработали. Я пытался поиграть с настройками appdomain / assembly в NUnit, пока безрезультатно.

Итак.

Кто-нибудь действительно запускал профилировщик памяти в тестовом проекте (любого типа — мы используем NUnit, но я бы поспорил, что это одно и то же для любого .Успешно NET automated testing framework)? Для какой-либо тестовой платформы .NET? Если да, то какие инструкции сработали у вас?

Ответ №1:

Когда мы сталкиваемся с проблемами, устраняющими неполадки в нашем приложении с помощью модульных тестов (некоторым из используемых нами библиотек не нравится запуск в среде модульного тестирования), мы просто создаем консольное приложение, которое вызывает методы тестирования в том же порядке, что и платформа модульного тестирования. Затем вы запускаете профилировщик в консольном приложении.

Возможно, вам не нужно запускать все тесты, чтобы выяснить, в чем заключается утечка.

Мы также столкнулись с утечками в неуправляемой памяти, которые не всегда видны из инструментов отслеживания управляемой памяти. Вам нужно специально искать неуправляемую память. Это часто является результатом отсутствия вызовов Dispose().

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

1. Это последнее средство, но спасибо за ответ. Мы используем все странные атрибуты, и я не хочу переопределять весь NUnit, но мы впадаем в отчаяние, так что в конечном итоге я могу это сделать.

2. После дополнительных проверок я не уверен, что проблема заключается в его использовании с NUnit. Вы пробовали добровольно вставлять утечки в свои тесты, чтобы посмотреть, сможет ли профилировщик их обнаружить? (просто добавьте материал в коллекцию между снимками) Возможно, что сами утечки находятся в месте, которое трудно обнаружить инструментами, и что сложность присуща самой утечке, а не инструменту. IIRC, последняя вкладка в профилировщике, предоставляет статистику относительно всего процесса. Однажды у меня была утечка, связанная с ADO .net, когда запрос передавал несколько K в неуправляемую память после каждого вызова.

3. Нет, он явно не показывает никаких данных из самих тестов. Я последовал вашему совету и создал консольный проект NUnit Питера и вчера провел несколько наших тестов, и я думаю, что обнаружил утечку. Мне просто любопытно, почему только я профилирую тестовые проекты. #probablydoingsomethingIshouldnt

Ответ №2:

Вам следует попробовать JetBrains MemoryProfiler (я использую версию 3.5) Он отлично работает на NUnit (версия с графическим интерфейсом)!

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

1. Попробовал, и это не сработало. Профилировщик производительности работает.

Ответ №3:

Я использовал последнюю версию RedGate ANTS (v9.5.0.853), и она корректно (и легко) профилировала мои библиотеки .NET через NUnit (v2.6.2).

Вам нужно настроить EXE для запуска как NUnit exe… И я нацелился на определенную функцию в моей DLL («Portal.Interface.dll «).

Я создал новый сеанс профиля;

  • Путь к исполняемому файлу .NET: C:Program Файлы (x86) NUnit 2.6.2binnunit-x86.exe
  • Аргументы командной строки: Портал.Interface.dll /приспособление:Портал.Интерфейс.Тесты.Скорость сериализации тестов
  • Рабочий каталог:

Затем я запустил его с использованием метода профилирования highest.

Это привело к результатам утечки, которые я ожидал…

Ответ №4:

Вы убедились, что рассмотрели все типы выделений, включая неуправляемую память?

Кстати, OutOfMemoryException не обязательно запускается, когда вообще нет свободной памяти. Иногда это вызывается определенными классами, которые хотят выделить большие смежные блоки памяти, например StringBuilder . XmlDocument.SelectNodes время от времени выдает его.

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

редактирование # 1

Возможно, я неправильно запомнил (виновато пиво), но ситуация, которую вы наблюдаете, также может быть объяснена тем фактом, что сборщик мусора сообщает, что он освободил объекты, но диспетчер памяти ОС не удосужился полностью освободить память, ранее занятую. У него даже больше прав делать то, что он чувствует, чем у .СЕТЕВОЙ сборщик мусора — это. Лучшее решение проблемы такого рода — проектировать вокруг всего, что пытается выделить массивные типы значений, наиболее заметные System.String .

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

1. Отрицательные ответы — пожалуйста, проявите порядочность и объясните, почему. Я лично сталкивался с проблемами, похожими на описанные, и основная причина заключается в том, что я упомянул в своем посте.

2. Проголосовал против, потому что это не помогает мне с моей проблемой сегодня. Возможно, это ответ на чей-то другой вопрос, но он не говорит мне, как запустить профилировщик в тестовом проекте.

3. Я думал, что объяснил себя достаточно хорошо — я хочу сказать, что я подозреваю, что вы не найдете то, что ищете, профилируя тестовый проект. Вопрос заключается в том, как профилировать тестовый проект, но проблема , с которой вы открываете вопрос, заключается в исключении OutOfMemoryException . Если это проблема, которую я описал, профилирование ее не обнаружит.