Is there any solution to this problem or is it a limitation of CLR memory management?
Нет решения, кроме пересмотра вашего дизайна. И это не проблема CLR. Обратите внимание, проблема та же для неуправляемых приложений. Это объясняется тем фактом, что приложение использует слишком много памяти одновременно и в сегментах, «невыгодно» размещаемых в памяти. Тем не менее, если нужно указать на какого-то внешнего виновника, я бы предпочел указать на диспетчер памяти ОС, который (конечно) не сжимает его адресное пространство vm.
CLR управляет свободными областями LOH в свободном списке. В большинстве случаев это лучшее, что можно сделать против фрагментации. Но поскольку для действительно больших объектов число объектов в сегменте LOH уменьшается - в конечном итоге мы получаем только один объект в сегменте. И где эти объекты расположены в пространстве VM, полностью зависит от менеджера памяти ОС. Это означает, что фрагментация в основном происходит на уровне ОС, а не на CLR. Это часто наблюдаемый аспект фрагментации кучи, и в этом не виноват .NET. (Но это также правда, фрагментация также может происходить на управляемой стороне, как хорошо продемонстрировано в этой статье .)
Общие решения уже названы: используйте ваши большие объекты повторно. Я до сих пор не сталкивался ни с одной ситуацией, когда это не могло быть сделано при правильном замысле. Тем не менее, это может быть сложно иногда и, следовательно, может быть дорогим, хотя.