Как вы можете исследовать управляемую кучу в приложении .NET для определения возможных оптимизаций памяти?

У нас есть приложение .NET, которое наши клиенты считают слишком большим для массового развертывания, и мы хотели бы понять, что способствует нашему пространству памяти, и можно ли сделать что-то лучше, не отказываясь от .NET и wpf.

Мы заинтересованы в улучшении как общего размера, так и личного рабочего набора (pws). В этом вопросе я просто хочу посмотреть на pws. VMMap обычно сообщает pws 105 мб. Из этого 11mb изображение, 31mb - куча, 52 mb - управляемая куча, 7 mb - личные данные, а остальное - стек, таблица страниц и т.д.

Крупнейшим призом здесь является управляемая куча. Мы можем составлять около 8 мб управляемой кучи непосредственно внутри нашего собственного кода, т.е. Объектов и окон, которые мы создаем и управляем. Остальные - предположительно .NET-объекты, созданные элементами используемой структуры.

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

Дальнейшие разъяснения:

Я использовал ряд инструментов до сих пор, включая отличные профили ANTS и WinDbg с SOS, и они позволяют мне видеть объекты в управляемой куче, но для настоящего интереса здесь нет "Что?", но 'Зачем?' В идеале я хотел бы сказать: "Ну, здесь создано 10 мб объектов, потому что мы используем WCF. Если мы напишем наш собственный родной транспорт, мы сможем сэкономить 8 МБ, что с риском x и рисками для развития".

Выполнение gcroot на 300 000 + объектов невозможно.

Ответ 1

WinDbg может быть полезным инструментом для вас. Он поставляется с Инструменты отладки для Windows.

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

Сначала вам нужно загрузить расширение SOS, которое позволяет отлаживать управляемые приложения:

.loadby sos mscorwks

Затем вы можете использовать !dumpheap для получения информации о куче, переключатель -stat дает общую информацию о куче, на которой выделяются типы:

!dumpheap -stat

Параметр -type предоставляет конкретную информацию о выделенных экземплярах указанного типа:

!dumpheap -type System.String

Там есть множество других команд, которые могут вам пригодиться:

  • !gcroot - следовать выделенному объекту, чтобы восстановить его корень, чтобы узнать, почему он находится в памяти.
  • !dumpobj - для выгрузки определенного объекта, чтобы вы могли видеть его содержимое.
  • !EEHeap - чтобы дать общую статистику кучи.

MSDN имеет полный список команд SOS и их переключатели.

WinDbg - довольно сложный инструмент, но есть много руководств и руководств в Интернете, если вы ищете, чтобы помочь вам начать работу. В качестве альтернативы, я могу порекомендовать книгу Отладка приложений Microsoft.NET 2.0 от Джона Роббинса, которая подробно рассказывает о возможностях отладки WinCC и WinDbg. SOS.

Вы можете загрузить расширение SOS в визуальную студию вместо этого, введя это в непосредственное окно, тогда вы должны иметь возможность использовать команды SOS непосредственно в непосредственном окне VS:

.load SOS.dll

Вы также можете найти CLR Profiler и этот руководство по использованию полезно.

Ответ 2

Новый инструмент PerfView, который может отображать дерево ссылок, а также выполнять разные функции

Ответ 3

Профилировщик CLR также отображает память, выделенную по типу в куче графически.

Ответ 4

Я использую .NET Profiler Profiler. Это также используется некоторыми командами Microsoft внутри страны, как сообщается подкастом PDC.

Ответ 5

Любой достойный профайлер памяти покажет вам эту информацию. Вы действительно не хотите возиться со свободным CLR Profiler, это не стоит вашего времени, получить достойный сторонний инструмент. Вы найдете их в этой теме.