Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What causes memory fragmentation in .NET

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?

like image 383
Matt Avatar asked Mar 09 '11 03:03

Matt


People also ask

What causes fragmented memory?

Fragmentation of memory can occur for relatively recent events as well. The impaired person usually suffers from physical damage to or underdevelopment of the hippocampus. This may be due to a genetic disorder or be the result of trauma, such as post-traumatic stress disorder.

How do I fix memory fragmentation?

Reducing the number of sizes between these extremes also helps. Employing sizes that increase logarithmically saves a lot of fragmentation. For example, each size could be 20% larger than the previous size. “One size fits all” might not be true for memory allocators in embedded system.

What is fragmentation in C#?

Fragmentation occurs in a dynamic memory allocation system when many of the free blocks are too small to satisfy any request. it is two type. 1- External 2-internal.

How does .NET manage memory?

In . NET, memory is managed through the use of Managed Heaps. Generally, in case of other languages, memory is managed through the Operating System directly. The program is allocated with some specific amount of memory for its use from the Raw memory allocated by the Operating system and then used up by the program.


2 Answers

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)?

like image 111
John Leidegren Avatar answered Oct 12 '22 16:10

John Leidegren


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.

like image 31
Daniel Earwicker Avatar answered Oct 12 '22 17:10

Daniel Earwicker