No More Memory Fragmentation on the .NET Large Object Heap

There are two different "types" of heaps in .NET. The Small Object Heap (SOH) and the Large Object Heap (LOH). One of the key differences between the heaps is that the SOH compacts memory and hence reduces the chance of memory fragmentation dramatically while the LOH does not employ compaction. As a result, excessive usage of the LOH may result in memory fragmentation that can become severe enough to cause problems in applications. In order to avoid potential memory fragmentation on the LOH, developers can use various techniques that involve writing additional code. With the advent of the newly released .NET Framework 4.5.1 (Preview), developers can now tell the CLR (garbage collector) to compact the LOH thereby avoiding memory fragmentation.

.NET 4.5.1 Preview now includes a new enumeration called GCLargeObjectHeapCompactionMode that has two fields:

  • CompactOnce - The next time a full GC occurs the LOH will be compacted. Once done, it reverts back to the default behavior which is non compacting.
  • Default - Default behavior is non compacting.

 

In order to set the LOH compaction mode using the enum above, simply use the GCSettings class and its corresponding LargeObjectHeapCompactionMode property:

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

GC.Collect(); // This will cause the LOH to be compacted (once).

 

The .NET 4.5.1 Preview can be downloaded from: https://www.microsoft.com/visualstudio/eng/2013-downloads

 As always, please note that this is a Preview release and as such functionality and behavior is subject to change.

Comments

  • Anonymous
    July 02, 2013
    Is this the proper way to invoke this when we're not sure we're running on .NET4.5.1? var piLOHCM = tGCSettings.GetProperty("LargeObjectHeapCompactionMode", BindingFlags.Static | BindingFlags.Public); if (null != piLOHCM ) {  var miSetter = piLOHCM.GetSetMethod();  miSetter.Invoke(null, new object[] { /* GCLargeObjectHeapCompactionMode.CompactOnce */ 2 })  GC.Collect();     // This will cause the LOH to be compacted (once). }

  • Anonymous
    November 16, 2013
    Why would you not know what .NET you are running on? You have to compile your app against 4.5.1 duh

  • Anonymous
    January 16, 2014
    B, I might be wrong but i think If you are building libraries, it is possible you might not know the version of .Net framework you are running on because the client application can choose to use a different version of .Net framework using the supportedRuntime tag in app.config file

  • Anonymous
    February 10, 2015
    If you're building libraries, your library shouldn't be doing LOH garbage collection. Your library should not be causing LOH fragmentation. This is something the application that is having the issue (due to bad libraries or their own code) might need to do.