What causes memory fragmentation in .NET

C#.NetMemory ManagementMemory LeaksFragmentation

C# Problem Overview


I am using Red Gates ANTS memory profiler to debug a memory leak. It keeps warning me that:

> Memory Fragmentation may be causing > .NET to reserver too much free memory.

or

> Memory Fragmentation is affecting the size of the largest object that can be allocated

Because I have OCD, this problem must be resolved.

What are some standard coding practices that help avoid memory fragmentation. Can you defragment it through some .NET methods? Would it even help?

C# Solutions


Solution 1 - C#

You know, I somewhat doubt the memory profiler here. The memory management system in .NET actually tries to defragment the heap for you by moving around memory (that's why you need to pin memory for it to be shared with an external DLL).

Large memory allocations taken over longer periods of time is prone to more fragmentation. While small ephemeral (short) memory requests are unlikely to cause fragmentation in .NET.

Here's also something worth thinking about. With the current GC of .NET, memory allocated close in time, is typically spaced close together in space. Which is the opposite of fragmentation. i.e. You should allocate memory the way you intend to access it.

Is it a managed code only or does it contains stuff like P/Invoke, unmanaged memory (Marshal.AllocHGlobal) or stuff like GCHandle.Alloc(obj, GCHandleType.Pinned)?

Solution 2 - C#

The GC heap treats large object allocations differently. It doesn't compact them, but instead just combines adjacent free blocks (like a traditional unmanaged memory store).

More info here: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

So the best strategy with very large objects is to allocate them once and then hold on to them and reuse them.

Solution 3 - C#

The .NET Framework 4.5.1, has the ability to explicitly compact the large object heap (LOH) during garbage collection.

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

See more info in GCSettings.LargeObjectHeapCompactionMode

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - C#John LeidegrenView Answer on Stackoverflow
Solution 2 - C#Daniel EarwickerView Answer on Stackoverflow
Solution 3 - C#Andre AbrantesView Answer on Stackoverflow