#c# #debugging #memory-leaks #pinvoke
#c# #отладка #утечки памяти #pinvoke
Вопрос:
Я разрабатываю приложение на C #, в котором, похоже, есть утечка. Я использовал профилировщик памяти и обнаружил, что мой
частные байты продолжают увеличиваться, но байты во всех кучах этого не делают, что означает, что, вероятно, это утечка собственной памяти
Теперь я застрял, как мне найти утечки памяти в машинном коде?
Комментарии:
1. Вы знаете, где утечка? Мы не сможем вам помочь без кода…
2. Вы не пишете машинный код на C #. Конечно, единственное, что вы можете сделать, это убедиться, что вы правильно обрабатываете взаимодействие?
3. Это обычная проблема с профилировщиками, они говорят вам больше, чем вы хотели знать. Увеличение частных байтов не является чем-то необычным, может потребоваться некоторое время, прежде чем оно стабилизируется. Вы действительно получаете исключения OutOfMemory? Если нет, то переверните бит игнорирования для этого.
4. @Karel Frajtak — а если я скажу вам, что код является следующим движком GOOGLE, вы позволите мне сохранить его в тайне?
5. Наткнулся на это от GOOGLE, задаваясь вопросом, использую ли я следующий движок GOOGLE с утечкой памяти, над которой работал Эрез.
Ответ №1:
Во-первых, если у вас есть дамп процесса утечки, вы можете открыть его в WinDbg и выполнить команду : !адрес -сводка
- если RegionUsageHeap большой, то это должна быть утечка собственной памяти
- если RegionUsageIsVAD, то это должна быть утечка памяти .NET.
Если это внутренняя утечка, то у вас есть 2 варианта :
-
Используйте DebugDiag: при появлении запроса выберите «Утечка собственной памяти и обработка утечки», выберите процесс, который вы хотите диагностировать, и начните работать с приложением, пока не проведете эксперимент с утечкой памяти. По завершении создайте полный дамп приложения (щелкните правой кнопкой мыши на правиле утечки и выберите Полный дамп пользователя). Затем вы можете проанализировать сгенерированный дамп (для эффективной работы вам нужно правильно настроить символы): на вкладке «Расширенный анализ» выберите «Анализаторы давления памяти», откройте файл дампа и нажмите «Начать анализ». Это создает отчет html, который вы можете проанализировать. Подробное пошаговое руководство можно найти на этой странице.
-
Используйте Application Verifier / WinDbg. В application verifier выберите ваше приложение (.exe). На странице тестов убедитесь, что выбран параметр Basics / Heaps . На нижней панели убедитесь, что для ‘Traces’ установлено значение true. После сохранения конфигурации повторно запустите приложение и создайте полный дамп при возникновении утечки. Не забудьте очистить флаги приложения после создания дампа. Затем вы можете открыть дамп из WinDbg и исследовать утечку с помощью команды ‘!heap’. В частности, ‘!heap -l’ выдаст вам список пропущенных блоков, ‘!heap -p -a ‘ покажет детали блока, включая стек вызовов выделения.
Если это утечка .NET, существуют сторонние инструменты для ее устранения. Начиная с версии 1.2, DebugDiag также позволяет выполнять анализ утечки памяти .NET (однако никогда не пробовал это делать).
Ответ №2:
Диагностика утечек собственной памяти в управляемом приложении (по крайней мере, на начальном этапе) очень похожа на диагностику утечек памяти в любом другом собственном приложении.
Обычно я подхожу к этим проблемам так: заставляю процесс пропускать большой объем памяти, создаю полный дамп процесса, а затем просматриваю дамп, чтобы увидеть, что использует больше всего памяти. Например, если ваш процесс имеет обычные / начальные частные байты ~ 20 МБ, но вы можете заставить свой процесс пропускать память до тех пор, пока у него не будет ~ 200 МБ личных байтов, тогда есть большая вероятность, что утечка ~ 180 МБ этой памяти — вообще говоря, все, что имеет большую часть выделенной памяти, — это то, где вы должныначните искать.
У Microsoft есть очень полезный инструмент под названием DebugDiag — изначально разработанный для диагностики утечек памяти в IIS. это очень энергозатратный инструмент и очень удобный при решении проблем с памятью. Если вы дадите ему аварийный дамп, он выполнит некоторый анализ и должен (по крайней мере) сообщить вам, какой модуль выделил всю эту память, затем вы можете начать более конкретно изучать, как используется этот модуль.
Ответ №3:
Трудно дать вам исчерпывающий ответ без дополнительной информации, но похоже, что библиотека, которую вы пытаетесь использовать, имеет утечку памяти. Вам понадобится библиотека с соответствующими инструментами, в зависимости от языка, на котором она была написана. Если у вас нет исходного кода библиотеки, свяжитесь с разработчиками и попросите их устранить утечку.
Если вы можете опубликовать имя библиотеки и часть вашего исходного кода (а также сигнатуры собственных методов), мы могли бы дать вам несколько более конкретных советов.
Ответ №4:
личные байты в кучах, управляемых .net framework, вам необходимо использовать профессиональный инструмент для анализа вашего источника. например, использовать профилировщик памяти red gate, найти созданный, но не удаляемый объект.
Ответ №5:
Обычно у меня были наилучшие результаты при поиске утечек памяти с помощью профилировщика памяти ANTS.
(Или другие инструменты, лично у меня был лучший опыт работы с ANTS)