Фрагментация на.NET LOH из-за закрепленных объектов

Я устраняю неполадки в приложении, написанном на.net 4.5 Asp.net + Unity 3.0.1304.1 + Nhibernate 3.3.1.4, которое потребляет от 3 до 5 ГБ памяти, что выше ожидаемого.

После сбора некоторых дампов памяти стало ясно, что в куче больших объектов произошла фрагментация.

Моей первой мыслью было обновить приложение до.net 4.5.1 и сказать GC о сжатии LOH, но мне стало известно количество закрепленных массивов объектов, что привело к демонстрационному приложению, в котором можно было сделать вывод, что сжатие кучи не было полезно в сценарии закрепленных объектов и даже не требуется, когда закрепленных объектов нет, поскольку отсутствует фрагментация.

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

Мои вопросы:

  • Как я могу продолжить, чтобы попытаться решить проблему фрагментации?
  • Как я могу получить больше информации о том, что находится в High Frequency Heap, так как команды, которые я знаю из WinDbg, не работают?

Над некоторыми отпечатками от windbg:

Экран загрузки
Dumpheap Показывает 618 свободных блоков
HeapStat Показывает размер и процент пустоты на LOH
gch есть 76 прикрепленных объектов, все в LOH
MRoot
MDT Содержимое одного из массивов
GCGen Показывает, что массивы действительно в LOH

1 ответ

Недавно я решил похожую проблему, описанную в этом вопросе: большой необъяснимый объем памяти в дампе памяти процесса.NET. Закрепленные объекты не были в высокочастотной куче, но были связаны с API асинхронного сокета. Обратите внимание, что объекты были byte[] таким образом, вероятно, не ваш случай.

Я не думаю, что закрепленные объекты в высокочастотной куче могут вызвать фрагментацию. Потому что это отдельная куча. В любом случае, ваши объекты на LOH.

Итак, во-первых, вам нужно определить, что создает (и прикрепляет) эти объекты. К сожалению, я не знаю простого метода. Вы должны попытаться определить код, создающий или закрепляющий эти объекты. Единственный способ, который я нашел в моем случае, - это запускать разные части кода по отдельности и создавать дамп для каждого... и мне в какой-то момент повезло. Может быть, вы можете посмотреть, как выглядит пиннинг. Но это может произойти в низкоуровневых частях CLR.

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