2013-08-13 2 views
2

Я не уверен, потому что у меня нет большого опыта в анализе дампов памяти, но я думаю, что у нас могут быть проблемы с фрагментацией памяти.Разрушение памяти?

Во время нагрузочных испытаний мы видим, что использование памяти растет до такой степени, что приложение перезапускается. Это приложение ASP.NET MVC 4 на 64-битной машине. Я не участвовал в написании. Мне просто попросили проанализировать дампы памяти.

Так что во время последнего теста нагрузки мы создали 3 дампы памяти (ниже их размеров и общий объем производства размера GC Heap из eeheap -gc):

  1. 1.70GB, 292MB
  2. 2.03GB, 337MB
  3. 2.55GB, 347MB

Таким образом, вы видите, что управляемая куча не растет, как файлы дампа. Когда я dumpheap -stat я вижу наиболее пространство используется бесплатных объектов (ниже для каждого файла дампа)

  1. 147MB
  2. 145MB
  3. 213MB
 
Fragmented blocks larger than 0.5 MB: 
      Addr  Size  Followed by 
000000bcc668e0a8 0.7MB 000000bcc6738650 System.Object[] 
000000bcc6949f88 4.4MB 000000bcc6dab820 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry 
000000bd4626c4b8 0.7MB 000000bd463165f8 System.Byte[] 
000000bd463fcc48 51.5MB 000000bd4977baf0 System.Threading.ThreadStart 
000000be463600c8 0.7MB 000000be464108f0 Free 
000000bec67e50e0 1.1MB 000000bec690b020 System.Collections.Generic.List`1[[OurType, ANotherOurType]] 
000000bec690b0b8 3.2MB 000000bec6c3b170 System.Byte[] 
000000bfc6605e00 1.0MB 000000bfc6710190 Free 
000000bfc6743c58 32.8MB 000000bfc8806fe8 System.Threading.ExecutionContext 
000000c046200580 1.0MB 000000c0462ff2a0 SomeOurType 
000000c0463a1270 3.6MB 000000c046732ac0 Microsoft.Win32.SafeHandles.SafeCapiKeyHandle 

От чего я понять, что это не проблема, когда бесплатные объекты составляют лишь небольшую часть общего объема памяти во всех размерах кучи. Здесь похоже, что это проблема.

Приложение использует две внешние библиотеки. Один для создания PDF-файлов и других для создания файлов штрих-кода. Библиотека штрих-кода бросает AccessViolationException (около 70 раз для 2200 попыток). Он выбрасывает эту стекю

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at System.Drawing.SafeNativeMethods.Gdip.IntGdipDeleteGraphics(HandleRef graphics) 
    at System.Drawing.Graphics.Dispose(Boolean disposing) 
    at System.Drawing.Graphics.Dispose() 
    at Lesnikowski.Barcode.BaseBarcode.Render() 
    at Lesnikowski.Barcode.BaseBarcode.Save(Stream stream, ImageType imageType) 

I've read that memory fragmentation is often caused by pinning memory, but this is !gchandles output

 
Handles: 
    Strong Handles:  154 
    Pinned Handles:  23 
    Ref Count Handles: 2 
    Weak Long Handles: 1794 
    Weak Short Handles: 74 
    SizedRef Handles:  17 
    Dependent Handles: 1 

I don't know what else I can check. Do we have memory fragmentation problem? Can you point me in some direction?

Edit: I attach performance counters collected during load test. Weird because it's showing a lot of pinned objects but !gchandles didn't show them.

enter image description here

 
red line - user load 
green line - bytes in all heaps 
blue line - pinned objects 

Edit2: Added Fragmented blocks larger than 0.5 MB: output from !dumpheap -stat

+2

Фрагментация памяти может вызвать OOM; однако это выглядит как простая ошибка BCL - это не должно быть ошибкой таким образом, фрагментировано или нет. –

+0

Вы имеете в виду эти AccessViolationExceptions? Это может быть ошибка BCL или нашего BarCode Libraries. Но я не уверен, что он каким-то образом связан с дампом памяти. –

ответ

2

You should use !address -summary, чтобы получить представление об использовании виртуальной памяти в этом процессе. Несмотря на то, что, по-видимому, существует фрагментация кучи, в вашем процессе очень вероятен дополнительный потребитель большой памяти. Это может быть куча Win32, это могут быть потоки стека, это могут быть сборки, которые вы загружаете динамически, и так далее.

Для каждого типа утечки вам необходимо будет придерживаться немного другого подхода. Для проверки кучи Win32 вы должны использовать изменения команды !heap - !heap -stat, !heap -s -h 0. Для проблем с загрузкой сборки вы должны посмотреть на кучу загрузчика с помощью !eeheap -loader, а затем просмотреть различные AppDomains у вас с !dumpdomain, чтобы узнать, какие сборки вы загружаете. Это лишь некоторые примеры - вам нужно будет предоставить более подробную информацию о вашей ситуации.

+0

Спасибо. Я думаю, что я уже нашел «утечку памяти». Это фрагментация LOH. Не успел обновить вопрос/предоставить ответ по моему собственному вопросу. –

Смежные вопросы