Профилирование LOH говорит, что корневые объекты GC (System.Object) являются источником утечки памяти

У меня есть HttpHandler который часто называют. Оно использует Entity Framework выполнить свою задачу.

Медленное увеличение используемой памяти w3p.exe этого веб-приложения (у него есть отдельный пул приложений). я использовал ANTS memory profiler и там много свободной памяти (ЛОХ). ANTS говорит, что это GC root объекты. Я проверил свой код, и есть несколько int а также string что не может привести к LOH!

Я проследил источник утечки, но, к сожалению, это типа System.Object с большим количеством null свойства. Также есть LinkedList, немного HashTableс и WeakHashTable,

Как я могу найти, что это за объект и исправить LOH? Как насчет возвращения true за IsReusable из HttpHandler?

1 ответ

Перво-наперво, вы должны отследить, что на самом деле происходит. В таких ситуациях мой первый инструмент всегда 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 использует при выделении объекта в куче больших объектов, который при попадании выгрузит полную трассировку стека, а затем продолжит.

Другие вопросы по тегам