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