Перво-наперво, вы должны отследить, что на самом деле происходит.В подобных ситуациях мой первый инструмент - всегда WinDbg.
http://www.windbg.org/ http://en.wikipedia.org/wiki/WinDbg
Чтобы использовать его с кодом управляемого / .NET, вам потребуетсяиспользовать расширение SOS (Son of Strike):
http://msdn.microsoft.com/en-us/library/bb190764.aspx
http://blogs.msdn.com/b/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx
Итак, как только вы подключили WinDbg к процессу w3wp.exe,Первое, что вы захотите сделать, это выяснить, что на самом деле находится в ваших кучах:
!dumpheap -stat
Это даст вам красиво отформатированное представление всех текущих «живых» объектов в памяти, а также сколькоиз них есть, сколько байтов они занимают, сгруппированные по типу объекта.
Теперь, куча больших объектов (LOH) - так обычно, когда объекты собирают мусор, происходит сжатие, вроде какдефрагментация жесткого диска.Это позволяет быстро и эффективно распределять новые объекты.Проблема в том, что крупные объекты нелегко сжать - все должно двигаться, чтобы вместить их.Таким образом, все, что занимает более 85000 байт, застревает в специальном месте, называемом кучей больших объектов.Эта куча НЕ сжимается, поэтому со временем, подобно жесткому диску, происходит фрагментация, оставляя неиспользуемые пробелы в куче, что приводит к тому, что среде выполнения требуется больше места и т. Д., И т. Д.
Итак, давайте спросим windbgчтобы сказать нам, что находится в LOH:
!dumpheap -stat -min 85000
Это покажет вам, что на самом деле находится в куче больших объектов - некоторые из этих объектов могут выпрыгнуть прямо на вас, например, List или MyClass [],
ВАЖНО: Если вещи, которые вы видите в куче больших объектов, являются преднамеренно долгоживущими (как, например, статический экземпляр регистратора), это, вероятно, на самом деле не проблема.Однако вы хотите попытаться уменьшить количество недолговечных / часто создаваемых объектов, чтобы уменьшить фрагментацию.
Итак, я рекомендую шпаргалку для исследования SOS:
http://windbg.info/doc/1-common-cmds.html
http://windbg.info/doc/2-windbg-a-z.html
Забавные команды:
!gcroot <address> <- will show you what object is "rooting" another
!CLRStack <- show current managed call stack
!dumpobj <address> <- show information about object at address
Но мой самый любимый из всех:
bp clr!SVR::gc_heap::allocate_large_object "!CLRStack; g;"
Который устанавливаетточка останова на фактическом внутреннем вызове, который CLR использует при выделении объекта в куче больших объектов, который при попадании выгрузит полную трассировку стека, а затем продолжит работу.