Что вызывает фрагментацию памяти в .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