Добавляю уточнение к ответу выше, с точки зрения того, как проблема может возникнуть. Фрагментация LOH зависит не только от долгоживущих объектов, но если у вас есть ситуация, когда существует несколько потоков, и каждый из них создает большие списки, идущие на LOH, то вы можете иметь ситуацию, когда первый поток необходимо увеличить свой список, но следующий непрерывный бит памяти уже занят списком из второго потока, поэтому среда выполнения будет выделять новую память для первого списка потоков, оставляя за собой довольно большую дыру. Это то, что происходит в настоящее время в одном проекте, который я унаследовал, и поэтому, несмотря на то, что LOH составляет приблизительно 4,5 МБ, среда выполнения имеет в общей сложности 117 МБ свободной памяти, но самый большой сегмент свободной памяти составляет 28 МБ.
Другой способ, которым это может произойти без нескольких потоков, - это если у вас есть несколько списков, добавляемых в какой-то цикл, и когда каждый из них выходит за пределы первоначально выделенной ему памяти, каждый из них перепрыгивает другой по мере их выхода за пределы их выделенные места.
Полезная ссылка: https://www.simple -talk.com / dotnet / .net-framework / куча опасных объектов /
Все еще ища решение для этого, один из вариантов может заключаться в использовании каких-либо объединенных объектов и запросе из пула при выполнении работы. Если вы имеете дело с большими массивами, тогда другой вариант - создать собственную коллекцию, например коллекция коллекций, чтобы у вас не было только одного огромного списка, но разбейте его на более мелкие списки, каждый из которых избегает LOH.