Что вызывает фрагментацию памяти в .NET.

Я использую профилировщик памяти ANTS Red Gates для отладки утечки памяти. Он предупреждает меня, что:

Фрагментация памяти может вызывать .NET для резервирования слишком большой свободной памяти.

или

Фрагментация памяти влияет на размер самого большого объекта, который может быть выделен

Поскольку у меня OCD, эта проблема должна быть решена.

Каковы некоторые стандартные методы кодирования, которые помогают избежать фрагментации памяти. Можете ли вы дефрагментировать его с помощью некоторых методов .NET? Помогло бы это?

Ответ 1

Знаешь, я несколько сомневаюсь в профайлере памяти здесь. Система управления памятью в .NET на самом деле пытается дефрагментировать кучу для вас, перемещаясь по памяти (поэтому вам нужно прикрепить память для совместного использования с внешней DLL).

Большие выделения памяти, взятые в течение более длительных периодов времени, подвержены большей фрагментации. Хотя небольшие эфемерные (короткие) запросы на память вряд ли вызовут фрагментацию в .NET.

Здесь также стоит подумать. С текущим GC.NET память, выделенная близко по времени, обычно располагается на расстоянии друг от друга в пространстве. Что противоположно фрагментации. т.е. вы должны распределять память так, как вы хотите получить к ней доступ.

Это только управляемый код или содержит такие вещи, как P/Invoke, неуправляемая память (Marshal.AllocHGlobal) или что-то вроде GCHandle.Alloc(obj, GCHandleType.Pinned)?

Ответ 2

Куча GC обрабатывает большие распределения объектов по-разному. Он не сжимает их, а просто объединяет смежные свободные блоки (например, традиционное неуправляемое хранилище памяти).

Дополнительная информация здесь: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

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

Ответ 3

.NET Framework 4.5.1 имеет возможность явно уплотнять кучу больших объектов (LOH) во время сбора мусора.

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();

См. дополнительную информацию в GCSettings.LargeObjectHeapCompactionMode