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

Я устраняю неполадки приложения, написанного на .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 Ответ

0 голосов
/ 23 ноября 2018

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...