Что вызывает фрагментацию памяти в .NET - PullRequest
47 голосов
/ 09 марта 2011

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

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

или

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

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

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

Ответы [ 3 ]

10 голосов
/ 09 марта 2011

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

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

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

9 голосов
/ 09 марта 2011

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

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

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

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

7 голосов
/ 02 января 2015

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

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

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

...