Утечка памяти с FileMonitorTarget / CacheDependency + DepFileInfo в ASP.NET - PullRequest
3 голосов
/ 27 июля 2010

В нашем веб-приложении ASP.NET мы наблюдаем довольно большую утечку памяти, которую я сейчас расследую. Используя WinDbg, я обратился к крупнейшим потребителям памяти в нашем приложении, которые (запустили !dumpheap -stat в консоли WinDbg, чтобы получить их):

MethodTable Addr   Count  Overall size Type
...
000007fee8306e10   212928     25551360 System.Web.UI.LiteralControl
000007feebf44748   705231     96776168 System.Object[]
000007fee838fd18  4394539    140625248 System.Web.Caching.CacheDependency+DepFileInfo
000007fee838e678  4394614    210941472 System.Web.FileMonitorTarget
000007feebf567b0    18259    267524784 System.Collections.Hashtable+bucket[]
00000000024897c0     1863    315249528      Free
000007feebf56cd0    14315    735545880 System.Byte[]
000007feebf4ec90  1293939   1532855608 System.String

Насколько я знаю, большое количество String объектов может быть вполне нормальным; все же определенно есть место для улучшения. Но что меня действительно зудит, так это количество System.Web.FileMonitorTarget объектов: у нас в куче более 4 миллионов экземпляров (48 байтов)! Используя два дампа памяти и сравнивая их, я обнаружил, что эти объекты не очищаются GC.

Я пытаюсь выяснить: откуда эти объекты? Я уже пробовал ANTS Memory Profiler, чтобы добраться до корня зла, но он не ведет ни к какому из наших собственных классов. Я вижу связь с System.Web.Caching.CacheDependency+DepFileInfo и, следовательно, с System.Web.Cache, но мы не используем файловые зависимости для аннулирования записей нашего кэша .

Кроме того, 14315 экземпляров System.Byte[] составляют более 700 МБ в куче, что меня оглушает - единственное место, где мы используем Byte[], - это наш компонент для загрузки изображений, но у нас есть только около 30 загрузок изображений в день. .

Что может быть источником этих Byte массивов и FileMonitorTarget объектов? Любые советы приветствуются!

Оливер

P.S. Кто-то задал почти тот же вопрос здесь , но единственный «ответ» был очень общим.

Ответы [ 2 ]

1 голос
/ 16 сентября 2010

Объекты типа System.Web.Caching.CacheDependency + DepFileInfo автоматически создаются ASP.NET для отслеживания изменений файлов на вашем веб-сайте. Таким образом, даже если вы не используете срок действия кэша FileDependency, ASP.NET сам по себе.

Если я запускаю поле дампа для некоторых из этих объектов, я получаю путь к моим элементам управления / страницам.

0:000> !df -field _filename 0d3f24ec 
Name: System.String
MethodTable: 79330b24
EEClass: 790ed65c
Size: 180(0xb4) bytes
GC Generation: 2
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: C:\inetpub\wwwroot\Website\Application\Base\UserControl\Messages.ascx
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79332d70  4000096        4         System.Int32  1 instance       82 m_arrayLength
79332d70  4000097        8         System.Int32  1 instance       81 m_stringLength
79331804  4000098        c          System.Char  1 instance       44 m_firstChar
79330b24  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  000e0ba0:02581198 00109f28:02581198 <<
79331754  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  000e0ba0:025816f0 00109f28:02586410 <<

Вы можете увидеть эту ссылку, описывающую немного более подробно: Понимание динамической компиляции ASP.NET

Однако ваш случай все еще может быть другим. Попробуйте запустить! GCRoot [obj_addr] и посмотрите, что удерживает эти объекты. В моем случае это полностью объекты, связанные с IIS / .NET.

Тем не менее, у меня все еще была проблема, когда были созданы миллионы этих объектов кэша, и я понятия не имею, почему. : | (это первый раз, когда это случилось со мной, но я не думаю, что оно появилось или исчезнет волшебным образом ...)

1 голос
/ 14 августа 2010

Есть пара вещей, которые я хотел бы рассмотреть.Вы правы, строки часто используются в большом количестве.Тем не менее у вас есть ок.1,4 Гб стоит строк в куче.Это звучит правильно?Если нет, я бы посмотрел на это.Если это в пределах ожидаемого диапазона, просто игнорируйте его.

Если вы подозреваете, что FileMonitorTarget и / или Byte[] имеют утечки, сбросьте экземпляры, используя !dumpheap -mt XXX, где XXX - это перечисленный MethodTable для типов.Возможно, вы захотите использовать PSSCOR2 вместо SOS, поскольку это немного облегчает эту задачу (вывод !dumpheap показывает дельта-столбец, и вы можете ограничить количество сбрасываемых экземпляров).сделать, это начать изучать то, что поддерживает конкретные экземпляры в живых.Команда !gcroot скажет вам, что является корнем конкретного экземпляра.Выберите случайный случай и осмотрите корни.Если все как положено, переходите к следующему.Если ваше приложение пропускает экземпляры этих типов, есть вероятность, что вы получите экземпляр, который должен был быть освобожден.Как только вы получите корни, вам нужно выяснить, какая часть кода удерживает их.Распространенным источником являются отписанные события, но есть и другие возможные причины, по которым объекты остаются живыми.

...