Фрагментация на.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.