Как найти, где память используется в C#?

У меня есть C# XNA в проекте WP7, и я нахожу, что он съедает память между изменениями экрана и не возвращает ее, в конечном итоге приводя к outofmemoryexception.

Я искал и искал, но я не могу за всю жизнь найти, куда идет это воспоминание.

есть ли способ узнать, где используется память и почему она не возвращается на устройство?

Спасибо за любую помощь!

6 ответов


используйте Microsoft профилировщик CLR для .NET Framework 4 (бесплатно) в версии Windows вашего проекта.

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

здесь случайная запись в блоге это имеет некоторые скриншоты и обсуждение профилировщика CLR в действии. (Не совсем то, что вы будете делать с ним, но полезное вступление, если вы никогда раньше не использовали профилировщик CLR.)

: потому что вы используете XNA, и вы обычно должны попробовать действительно трудно заставить C# работать из управляемой памяти, у вас, вероятно, заканчивается неуправляемые память. Есть ли где-то, куда вы не звоните Dispose() прежде чем вы прекратите использовать графический или звуковой объект, который вы создали? Я обсудил детали этого пару времени.

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


можно попробовать профилировщик памяти Муравьев Redgate (но это стоит), и я не уверен, что использую его с WP7, но это для C#.

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


Eqatec есть профилировщик, который работает с WP7. Это не профайлер памяти, но я бы попробовал посмотреть, что он показывает. Это может помочь вам выбрать правильное направление.


на coding4fun toolkit содержит счетчик памяти, который помогает отслеживать использование памяти приложения. здесь документация и статьи демонстрации его использования.


использовать профилировщик среды CLR для .NET Framework 2.0. По умолчанию он не поддерживается в XNA 4.0, но у Дэйва на дерьмовом кодировании есть решение.


один я использую Mono profiler. Он имеет различные варианты; самое простое использование

mono --profile=log program.exe

а затем, после program.exe выйдет, он оставит файл профилировщика (output.mlpd по умолчанию), а для чтения собранной информации используйте:

mprof-report output.mlpd

Е. Г. Я делаю mprof-report output.mlpd | vim -.

по умолчанию он собирает кучу различной информации. В самом начале вывода (даны настройки по умолчанию) вы увидите таблица функций, отсортированных по столбцу "выделено", например snip:

Allocation summary
  24      Bytes      Count  Average Type name
  25    7357392     306558       24 System.IntPtr
  26    6677904     139123       48 System.Collections.ArrayList.ArrayListEnumeratorSimple
  27    5842736     136185       42 Mono.Unix.Native.Syscall._pollfd[]
  28    3078176      49566       62 System.Byte[]
  29    2574504      38057       67 System.String
  30     908320      14803       61 System.Int32[]
  31     719984       5294      136 Mono.Globalization.Unicode.SortKeyBuffer

его преимущества из моего ума:

  • это кроссплатформа, поэтому вы можете легко профилировать распределения .net RAM на GNU / Linux и Mac.
  • он разработан создателями и крупнейшими пользователями .net-Microsoft. Раньше он был разработан Xamarin, но MS купила их, и теперь они упоминаются на главной странице Mono.